package com.yanqu.road.server.manager.activity.xingyou;

import com.yanqu.road.dao.impl.activity.xingyoushanshui.XingYouShanShuiConfigDaoImpl;
import com.yanqu.road.dao.impl.activity.xingyoushanshui.cross.*;
import com.yanqu.road.entity.activity.ActivityConfig;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.commonteam.data.CommonTeamUserData;
import com.yanqu.road.entity.activity.youxing.*;
import com.yanqu.road.entity.activity.youxing.config.XingYouConfig;
import com.yanqu.road.entity.activity.youxing.config.XingYouShanShuiEventInfo;
import com.yanqu.road.entity.activity.youxing.config.XingYouShanShuiGridInfo;
import com.yanqu.road.entity.activity.youxing.config.XingYouShanShuiRoleInfo;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.log.cross.xingyou.*;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.logic.bussiness.servercenter.ActivityBussiness;
import com.yanqu.road.logic.helper.RandomWeightConfigHelper;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.pb.activity.XingYouShanShuiProto;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.manager.activity.commonteam.CommonTeam;
import com.yanqu.road.server.manager.activity.commonteam.CommonTeamActivity;
import com.yanqu.road.server.manager.activity.commonteam.CommonTeamMgr;
import com.yanqu.road.server.manager.activity.xingyou.enums.eXingYouGridTypes;
import com.yanqu.road.server.manager.activity.xingyou.inter.GridHandleResult;
import com.yanqu.road.server.manager.activity.xingyou.inter.IXingYouGridHandler;
import com.yanqu.road.server.manager.activity.xingyou.inter.grid.WishGridHandler;
import com.yanqu.road.server.manager.activity.xingyou.task.CrossXingYouSendCaptorRewardTask;
import com.yanqu.road.server.manager.log.CrossAutoLogMgr;
import com.yanqu.road.server.manager.user.CrossUserMgr;
import com.yanqu.road.server.manger.ServerLanguageMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;
import org.apache.mina.util.ConcurrentHashSet;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

public class CrossXingYouActivity {

    /**
     * 分组id
     */
    private int groupId;
    /**
     * 活动锁
     * 统一加锁顺序，避免死锁
     * 队伍成员十连锁(避免服务端自动操作读取到不一致的队伍数据状态) > 玩家执行锁（避免玩家自己并发） > 活动锁（操作多个队伍数据；或者全局共享如妈祖数据） > 队伍锁（队伍锁不能嵌套，最小锁，操作玩家或者队伍共享数据）
     * 需要操作其他玩家数据的，都用对应的队伍锁；操作玩家数据都用队伍锁
     */
    private Object lock = new Object();

    /**
     * 全局临时数据
     */
    private Map<String, Object> globalMap = new ConcurrentHashMap<>();

    /**
     * 活动配置
     */
    protected XingYouConfig config;

    /**
     * 活动数据
     */
    private CrossXingYouShanShuiData shanShuiData;

    /**
     * 队伍数据
     */
    private Map<Integer, CrossXingYouShanShuiTeamData> teamDataMap;

    /**
     * 队伍地图数据
     */
    private Map<Integer, Map<Integer, CrossXingYouShanShuiTeamMapData>> teamMapDataMap;

    /**
     * 玩家数据
     */
    private Map<Long, CrossXingYouShanShuiUserData> userDataMap;

    /**
     * 队伍日志
     */
    private Map<Integer, List<CrossXingYouShanShuiTeamActionLogData>> teamLogMap;
    private AtomicLong maxActionId;
    private List<CrossXingYouShanShuiTeamActionLogData> teamLogUpdateList = new ArrayList<>();

    /**
     * 队伍标记
     */
    private Map<Integer, List<CrossXingYouTargetMarkData>> teamMarkMap;
    private AtomicLong maxMarkId;
    private List<CrossXingYouTargetMarkData> teamMarkUpdateList = new ArrayList<>();


    /**
     * 建筑日志
     */
    private Map<Integer, List<CrossXingYouShanShuiBuildingLogData>> buildLogMap;
    private AtomicLong maxBuildLogId;
    private List<CrossXingYouShanShuiBuildingLogData> buildingLogDataUpdateList = new ArrayList<>();


    /**
     * 衙门抓捕日志
     */
    private Map<Integer, List<CrossXingYouShanShuiCatchLogData>> teamCatchDataMap;
    private AtomicLong maxCatchLogId;
    private List<CrossXingYouShanShuiCatchLogData> logCatchDataUpdateList = new ArrayList<>();


    /**
     * 祈愿奖励
     */
    private Map<Integer, List<CrossXingYouShanShuiWishRewardData>> teamWishRewardMap;
    private List<CrossXingYouShanShuiWishRewardData> wishRewardDataUpdateList = new ArrayList<>();


    /**
     * 地图内的玩家
     */
    private ConcurrentHashSet<Long> inMapUserSet = new ConcurrentHashSet<>();

    /**
     * 需要同步红点的队伍
     */
    private ConcurrentHashSet<Integer> needSyncRedDotTeamMap = new ConcurrentHashSet<>();
    /**
     * 需要同步红点的玩家
     */
    private ConcurrentHashSet<Long> needSyncRedDotUserMap = new ConcurrentHashSet<>();

    public CrossXingYouActivity(ActivityInfo activityInfo, int groupId) {
        this.groupId = groupId;
        reloadConfig(activityInfo);

        userDataMap = new CrossXingYouShanShuiUserDataDaoImpl().getCrossXingYouShanShuiUserData(activityInfo.getActivityId(), this.groupId);
        teamDataMap = new CrossXingYouShanShuiTeamDataDaoImpl().getCrossXingYouShanShuiTeamData(activityInfo.getActivityId(), this.groupId);
        shanShuiData = new CrossXingYouShanShuiDataDaoImpl().getCrossXingYouShanShuiData(activityInfo.getActivityId(), this.groupId);
        if(shanShuiData == null){
            CrossXingYouShanShuiData tempShanShuiData = new CrossXingYouShanShuiData();
            tempShanShuiData.setGroupId(this.groupId);
            tempShanShuiData.setActivityId(activityInfo.getActivityId());
            tempShanShuiData.setDayRestTime(DateHelper.getTodayZeroTimeStamp());
            tempShanShuiData.setInsertOption();
            initMaZu(tempShanShuiData);
            shanShuiData = tempShanShuiData;
        }
        teamMapDataMap  = new CrossXingYouShanShuiTeamMapDataDaoImpl().getCrossXingYouShanShuiTeamMapData(activityInfo.getActivityId(), this.groupId);

        teamLogMap = new CrossXingYouShanShuiTeamActionLogDataDaoImpl().getCrossXingYouShanShuiTeamActionLogData(activityInfo.getActivityId(), this.groupId, config.getSHANSHUI_LOG_LIMIT());
        for (Map.Entry<Integer, List<CrossXingYouShanShuiTeamActionLogData>> entry : teamLogMap.entrySet()) {
            entry.getValue().sort(Comparator.comparingLong(CrossXingYouShanShuiTeamActionLogData::getLogTime));
        }
        maxActionId = new AtomicLong(new CrossXingYouShanShuiTeamActionLogDataDaoImpl().getMaxId(activityInfo.getActivityId(), this.groupId));

        teamMarkMap = new CrossXingYouTargetMarkDataDaoImpl().getCrossXingYouTargetMarkData(activityInfo.getActivityId(), this.groupId, config.getSHANSHUI_BATTLE_LOG_LIMIT());
        maxMarkId = new AtomicLong(new CrossXingYouTargetMarkDataDaoImpl().getMaxId(activityInfo.getActivityId(), this.groupId));

        buildLogMap = new CrossXingYouShanShuiBuildingLogDataDaoImpl().getCrossXingYouShanShuiBuildingLogData(activityInfo.getActivityId(), this.groupId);
        maxBuildLogId = new AtomicLong(new CrossXingYouShanShuiBuildingLogDataDaoImpl().getMaxId(activityInfo.getActivityId(), this.groupId));

        teamCatchDataMap = new CrossXingYouShanShuiCatchLogDataDaoImpl().getCrossXingYouShanShuiCatchLogData(activityInfo.getActivityId(), this.groupId);
        maxCatchLogId = new AtomicLong(new CrossXingYouShanShuiCatchLogDataDaoImpl().getMaxId(activityInfo.getActivityId(), this.groupId));

        teamWishRewardMap = new CrossXingYouShanShuiWishRewardDataDaoImpl().getCrossXingYouShanShuiWishRewardData(activityInfo.getActivityId(), this.groupId);

    }

    //初始npc妈祖
    private void initMaZu(CrossXingYouShanShuiData tempShanShuiData) {
        tempShanShuiData.setUserId(0);
        long ability = 0;
        List<ShanShuiBeauty> beautyList = new ArrayList<>();
        for (String string : config.getSHANSHUI_DEFAULT_MONSTER()) {
            List<Integer> list = StringUtils.stringToIntegerList(string, ",");
            ShanShuiBeauty beauty = new ShanShuiBeauty();
            beauty.setId(list.get(0));
            beauty.setMacy(list.get(1));
            beauty.setMour(list.get(2));
            beautyList.add(beauty);
            ability += (beauty.getMacy() + beauty.getMour());
        }
        tempShanShuiData.setBeautyList(beautyList);
        tempShanShuiData.setTotalHp(ability);
        tempShanShuiData.setHp(ability);
    }

    public void save(){

        for (Map.Entry<Long, CrossXingYouShanShuiUserData> entry : userDataMap.entrySet()) {
            CrossXingYouShanShuiUserData value = entry.getValue();
            if(value.isInsertOption()){
                new CrossXingYouShanShuiUserDataDaoImpl().add(value);
            }else if(value.isUpdateOption()){
                new CrossXingYouShanShuiUserDataDaoImpl().update(value);
            }
        }

        for (Map.Entry<Integer, Map<Integer, CrossXingYouShanShuiTeamMapData>> entry : teamMapDataMap.entrySet()) {
            Map<Integer, CrossXingYouShanShuiTeamMapData> value = entry.getValue();
            for (Map.Entry<Integer, CrossXingYouShanShuiTeamMapData> dataEntry : value.entrySet()) {
                CrossXingYouShanShuiTeamMapData data = dataEntry.getValue();
                if(data.isInsertOption()){
                    new CrossXingYouShanShuiTeamMapDataDaoImpl().add(data);
                }else if(data.isUpdateOption()){
                    new CrossXingYouShanShuiTeamMapDataDaoImpl().update(data);
                }
            }
        }

        for (Map.Entry<Integer, CrossXingYouShanShuiTeamData> entry : teamDataMap.entrySet()) {
            CrossXingYouShanShuiTeamData value = entry.getValue();
            if(value.isInsertOption()){
                new CrossXingYouShanShuiTeamDataDaoImpl().add(value);
            }else if(value.isUpdateOption()){
                new CrossXingYouShanShuiTeamDataDaoImpl().update(value);
            }
        }

        if(shanShuiData.isInsertOption()){
            new CrossXingYouShanShuiDataDaoImpl().add(shanShuiData);
        }else if(shanShuiData.isUpdateOption()){
            new CrossXingYouShanShuiDataDaoImpl().update(shanShuiData);
        }

        List<CrossXingYouShanShuiTeamActionLogData> needActionList = null;
        synchronized (teamLogUpdateList){
            if(teamLogUpdateList.size() > 0){
                needActionList = new ArrayList<>(teamLogUpdateList);
                teamLogUpdateList.clear();
            }
        }
        if(needActionList != null){
            for (CrossXingYouShanShuiTeamActionLogData data : needActionList) {
                if(data.isInsertOption()){
                    new CrossXingYouShanShuiTeamActionLogDataDaoImpl().add(data);
                }else if(data.isUpdateOption() && data.getEventId() == 3){
                    new CrossXingYouShanShuiTeamActionLogDataDaoImpl().update(data);
                }
            }
        }

        List<CrossXingYouTargetMarkData> needList = null;
        synchronized (teamMarkUpdateList){
            if(teamMarkUpdateList.size() > 0){
                needList = new ArrayList<>(teamMarkUpdateList);
                teamMarkUpdateList.clear();
            }
        }
        if(needList != null){
            for (CrossXingYouTargetMarkData markData : needList) {
                if(markData.isInsertOption()){
                    new CrossXingYouTargetMarkDataDaoImpl().add(markData);
                }else if(markData.isUpdateOption()){
                    new CrossXingYouTargetMarkDataDaoImpl().update(markData);
                }
            }
        }

        List<CrossXingYouShanShuiBuildingLogData> needBuildList = null;
        synchronized (buildingLogDataUpdateList){
            if(buildingLogDataUpdateList.size() > 0){
                needBuildList = new ArrayList<>(buildingLogDataUpdateList);
                buildingLogDataUpdateList.clear();
            }
        }
        if(needBuildList != null){
            for (CrossXingYouShanShuiBuildingLogData buildingLogData : needBuildList) {
                if(buildingLogData.isInsertOption()){
                    new CrossXingYouShanShuiBuildingLogDataDaoImpl().add(buildingLogData);
                }else if(buildingLogData.isUpdateOption()){

                }
            }
        }

        List<CrossXingYouShanShuiCatchLogData> needCatchList = null;
        synchronized (logCatchDataUpdateList){
            if(logCatchDataUpdateList.size() > 0){
                needCatchList = new ArrayList<>(logCatchDataUpdateList);
                logCatchDataUpdateList.clear();
            }
        }
        if(needCatchList != null){
            for (CrossXingYouShanShuiCatchLogData buildingLogData : needCatchList) {
                if(buildingLogData.isInsertOption()){
                    new CrossXingYouShanShuiCatchLogDataDaoImpl().add(buildingLogData);
                }else if(buildingLogData.isUpdateOption()){

                }
            }
        }

        List<CrossXingYouShanShuiWishRewardData> needWishRewardList = null;
        synchronized (wishRewardDataUpdateList){
            if(wishRewardDataUpdateList.size() > 0){
                needWishRewardList = new ArrayList<>(wishRewardDataUpdateList);
                wishRewardDataUpdateList.clear();
            }
        }
        if(needWishRewardList != null){
            for (CrossXingYouShanShuiWishRewardData rewardData : needWishRewardList) {
                if(rewardData.isInsertOption()){
                    new CrossXingYouShanShuiWishRewardDataDaoImpl().add(rewardData);
                }else if(rewardData.isUpdateOption()){
                    new CrossXingYouShanShuiWishRewardDataDaoImpl().update(rewardData);
                }
            }
        }

    }

    public XingYouConfig getConfig() {
        return config;
    }

    public void reloadConfig(ActivityInfo activityInfo) {
        Map<String, ActivityConfig> activityConfigMap = ActivityBussiness.getActivityConfigMap(Collections.singletonList(activityInfo.getActivityId())).get(activityInfo.getActivityId());
        XingYouConfig tmpConfig = new XingYouConfig();
        tmpConfig.setActivityInfo(activityInfo);

        XingYouShanShuiConfigDaoImpl configDao = new XingYouShanShuiConfigDaoImpl();
        tmpConfig.setRoleInfoList(configDao.getXingYouShanShuiRoleInfoList(activityInfo.getActivityId()));
        tmpConfig.setEventInfoList(configDao.getXingYouShanShuiEventInfoList(activityInfo.getActivityId()));
        tmpConfig.setGridInfoList(configDao.getXingYouShanShuiGridInfoList(activityInfo.getActivityId()));

        // 初始化配置
        tmpConfig.initConfig(activityConfigMap);
        config = tmpConfig;
    }

    public void reloadConfig() {
        reloadConfig(config.getActivityInfo());
    }

    /**
     * 进入活动
     */
    public void enterByCmd(long serverId, long playerId) {

        CommonTeamActivity teamActivity = CommonTeamMgr.getActivity(config.getActivityInfo().getActivityId(), this.groupId);
        if(teamActivity == null){
            return;
        }

        CrossXingYouShanShuiUserData userData = getUserData(playerId);

        CommonTeamUserData teamUserData = teamActivity.getUserData(playerId);
        if(teamUserData != null && userData.getTeamId() == 0){
            userData.setTeamId(teamUserData.getTeamId());
        }

        if(userData.getRoleId() <= 0 && userData.getTeamId() > 0){
            userData.setRoleId(randomRoleId(userData.getTeamId()));
        }

        XingYouShanShuiProto.ShanShuiEnterRsp.Builder respMsg = XingYouShanShuiProto.ShanShuiEnterRsp.newBuilder();
        respMsg.setActivityId(config.getActivityInfo().getActivityId());
        respMsg.setRet(0);
        respMsg.setActivityId(config.getActivityInfo().getActivityId());
        respMsg.setConsumeEnergy(userData.getUseEnergy());

        if(userData.getTeamId() > 0){
            //队伍总消耗
            respMsg.setUseEnergyTotal(getTeamTotalUseEnergy(userData.getTeamId()));
            CommonTeamActivity activity = CommonTeamMgr.getActivity(config.getActivityInfo().getActivityId(), this.groupId);
            if(activity != null){
                CommonTeam team = activity.getTeam(userData.getTeamId());
                if(team != null){
                    //角色分配
                    for (Map.Entry<Long, CommonTeamUserData> entry : team.getMemberDataMap().entrySet()) {
                        XingYouShanShuiProto.ShanShuiRoleBindInfo.Builder builder = XingYouShanShuiProto.ShanShuiRoleBindInfo.newBuilder();
                        builder.setUserId(entry.getKey());
                        CrossXingYouShanShuiUserData data = getUserData(entry.getKey());
                        builder.setRoleId(data.getRoleId());
                        respMsg.addRoleBindInfos(builder);
                    }
                }
            }
        }

        //红点
        respMsg.setRedValue(calUserRedValue(userData.getUserId()));

        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_XING_YOU_SHAN_SHUI_ENTER, respMsg));
    }

    /**
     * 进入地图
     */
    public void enterMapByCmd(long serverId, long playerId, String language) {
        CommonTeamActivity teamActivity = CommonTeamMgr.getActivity(config.getActivityInfo().getActivityId(), this.groupId);
        if(teamActivity == null){
            return;
        }
        CrossXingYouShanShuiUserData userData = getUserData(playerId);

        if(userData.getTeamId() <= 0){
            return;
        }

        synchronized (getUserLocker(userData.getUserId())){
            //体力刷新
            refreshUserEnergy(userData, true);
        }
        if(!StringUtils.isNullOrEmpty(language)){
            userData.setLanguage(language);
        }
        //成员
        List<Long> memberList = new ArrayList<>();
        XingYouShanShuiProto.ShanShuiEnterMapRsp.Builder respMsg = XingYouShanShuiProto.ShanShuiEnterMapRsp.newBuilder();
        CommonTeam team = teamActivity.getTeam(userData.getTeamId());
        if(team != null){
            for (Map.Entry<Long, CommonTeamUserData> entry : team.getMemberDataMap().entrySet()) {
                memberList.add(entry.getKey());
            }
        }
        for (long memberId : memberList) {
            CrossXingYouShanShuiUserData member = getUserData(memberId);
            XingYouShanShuiProto.ShanShuiMemberInfo.Builder builder = getMemberBuilder(member, false);
            respMsg.addMemberInfoList(builder);
        }

        if(userData.getTeamId() > 0){
            CrossXingYouShanShuiTeamData teamData = getTeamData(userData.getTeamId());
            if(team != null){
                XingYouShanShuiProto.ShanShuiTeamInfo.Builder teamInfoBuilder = getTeamBuilder(userData, memberList, team, teamData);
                respMsg.setTeamInfo(teamInfoBuilder);
            }
        }
        //是否有漂泊结算
        synchronized (getUserLocker(userData.getUserId())){
            if(userData.isDrift() && userData.getDriftEndType() < -1){

                //客户端结果
                XingYouShanShuiProto.ShanShuiDriftResultInfo.Builder driftResult = XingYouShanShuiProto.ShanShuiDriftResultInfo.newBuilder();
                driftResult.setState(userData.getDriftEndType());
                //结算
                catchSettle(userData);

                Property driftReward = userData.getDriftReward();

                //重置状态
                userData.setDriftReward(new Property());
                userData.setDriftEndType(0);
                userData.setStartDriftTime(0);
                int mapTeamId = userData.getMapTeamId();
                userData.setMapTeamId(0);
                userData.getDriftGridParam().setEventId(0);
                userData.getDriftGridParam().setHandled(true);
                addReward(userData, driftReward, false, 7);
                driftResult.setReward(PropertyHelper.parsePropertyToString(driftReward));
                respMsg.setDriftResult(driftResult);
                userData.setUpdateOption();

                //离开
                CrossXingYouShanShuiTeamData teamData = getTeamData(mapTeamId);
                teamData.getVisitorMap().remove(userData.getUserId());
                teamData.setUpdateOption();

                CommonTeam driftTeam = CommonTeamMgr.getTeam(config.getActivityInfo().getActivityId(), this.groupId, mapTeamId);

                CrossXingYouShanShuiTeamActionLogData actionLogData = createActionLogData(userData, XingYouShanShuiProto.ShanShuiLogTypeEnum.SHAN_SHUI_LOG_FERRY_TERMINAL, PropertyHelper.parsePropertyToString(driftReward),
                        Arrays.asList(String.valueOf(userData.getRoleId()), driftTeam == null ? "" : driftTeam.getTeamName()));
                addCrossXingYouShanShuiTeamActionLogData(actionLogData);

                //离开漂泊通知
                syncDriftState(playerId, mapTeamId, 0);
            }
        }

        XingYouShanShuiProto.ShanShuiPlayerInfo.Builder playerInfoBuilder = getPlayerInfoBuilder(userData);
        respMsg.setPlayerInfo(playerInfoBuilder);

        XingYouShanShuiProto.ShanShuiMapInfo.Builder mapInfoBuilder = getMapInfoBuilder(userData.getTeamId());

        if(userData.isDrift()) {
            XingYouShanShuiProto.ShanShuiDriftInfo.Builder driftInfo = getDriftInfo(userData.getMapTeamId(), userData);
            if(driftInfo != null) {
                respMsg.setDriftInfo(driftInfo);
            }
        }else {
            if(mapInfoBuilder != null) {
                respMsg.setMapInfo(mapInfoBuilder);
            }
        }
        respMsg.setRet(0);
        XingYouShanShuiProto.CrossShanShuiEnterMapRsp.Builder crossRsp = XingYouShanShuiProto.CrossShanShuiEnterMapRsp.newBuilder();
        crossRsp.setRsp(respMsg);
        crossRsp.setSilverCoinTotal(userData.getSilverCoinTotal());
        crossRsp.setRound(userData.getRound());
        crossRsp.setUseEnergyTotal(userData.getUseEnergy());
        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.S_XING_YOU_SHAN_SHUI_ENTER_MAP_FROM_CROSS, crossRsp));

        syncTeamData(userData, false);
        inMapUserSet.add(userData.getUserId());

        needSyncRedDotUserMap.add(userData.getUserId());
    }

    private XingYouShanShuiProto.ShanShuiTeamInfo.Builder getTeamBuilder(CrossXingYouShanShuiUserData userData, List<Long> memberList, CommonTeam team, CrossXingYouShanShuiTeamData teamData) {
        XingYouShanShuiProto.ShanShuiTeamInfo.Builder teamInfoBuilder = XingYouShanShuiProto.ShanShuiTeamInfo.newBuilder();
        teamInfoBuilder.setTeamId(userData.getTeamId());
        teamInfoBuilder.setCreateTime(team.getCreateTime());
        teamInfoBuilder.setMemberNum(memberList.size());
        teamInfoBuilder.setLeaderId(team.getLeaderId());
        UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(team.getLeaderId());
        if(userBaseInfo != null){
            teamInfoBuilder.setLeaderName(userBaseInfo.getNickName());
            teamInfoBuilder.setLeaderServerId(userBaseInfo.getServerId());
        }
        teamInfoBuilder.setTeamName(team.getTeamName());
        if(teamData != null) {
            teamInfoBuilder.setSilverCoin((int)teamData.getSilverCoin());
            teamInfoBuilder.setSilverCoinTotal((int)teamData.getSilverCoinTotal());
        }
        teamInfoBuilder.setRank(0);
        CommonTeamActivity activity = CommonTeamMgr.getActivity(config.getActivityInfo().getActivityId(), this.groupId);
        if(activity != null){
            int teamRank = activity.getTeamRank(userData.getTeamId(), eGamePlayerEventType.XingYouShanShuiTeamSliverRank.getValue());
            teamInfoBuilder.setRank(teamRank);
        }
        return teamInfoBuilder;
    }

    /**
     * 小队是否进驻妈祖
     */
    public boolean inMazuTemp(CrossXingYouShanShuiUserData userData){
        long userId = shanShuiData.getUserId();
        if(userId <= 0){
            return false;
        }
        CrossXingYouShanShuiUserData maZuData = getUserData(userId);
        if(userData.getTeamId() == maZuData.getTeamId()){
            return true;
        }
        return false;
    }

    /**
     * 投骰子
     * @param diceType
     * @param dice
     * @param tongXingNum 已有的通行证数量
     */
    public void diceByCmd(long serverId, long playerId, int diceType, int dice, int tongXingNum) {

        XingYouShanShuiProto.CrossShanShuiDiceRsp.Builder respMsg = XingYouShanShuiProto.CrossShanShuiDiceRsp.newBuilder();
        respMsg.setDiceType(diceType);
        respMsg.setReward("");

        XingYouShanShuiProto.ShanShuiDiceRsp.Builder clientMsg = XingYouShanShuiProto.ShanShuiDiceRsp.newBuilder();
        CrossXingYouShanShuiUserData userData = getUserData(playerId);

        if(userData.getTeamId() <= 0){
            return;
        }
        //漂泊状态只能用漂泊骰子
        if(userData.isDrift() && diceType != 4){
            clientMsg.setRet(GameErrorCode.E_REQUEST_ARGUMENT_ERROR);
            respMsg.setClientMsg(clientMsg);
            MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.S_XING_YOU_SHAN_SHUI_DICE_FROM_CROSS, respMsg));
            return;
        }
        if(!userData.isDrift() && userData.getFlyTimes() > 0 && diceType != 5){
            clientMsg.setRet(GameErrorCode.E_REQUEST_ARGUMENT_ERROR);
            respMsg.setClientMsg(clientMsg);
            MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.S_XING_YOU_SHAN_SHUI_DICE_FROM_CROSS, respMsg));
            return;
        }
        //随机下队伍数据
        CrossXingYouShanShuiTeamData teamData = getTeamData(userData.getTeamId());
        synchronized (getTeamData(userData.getTeamId())){
            if(teamData.getRandomTodayTeam().size() < 5){
                teamData.getRandomTodayTeam().addAll(randomTeam(teamData));
            }
        }

        //投骰子之前是否是漂泊状态
        boolean drift = userData.isDrift();
        int driftMapTeamId = userData.getMapTeamId();
        XingYouShanShuiProto.ShanShuiMoveInfo.Builder moveInfoBuilder = XingYouShanShuiProto.ShanShuiMoveInfo.newBuilder();
        Property property = new Property();
        boolean containSilver;
        synchronized (getUserLocker(playerId)){

            //如果是漂泊状态，未结算
            if(userData.isDrift() && userData.getDriftEndType() < -1){
                clientMsg.setRet(GameErrorCode.E_XING_YOU_SHAN_SHUI_SETTLE_DRIFT);
                respMsg.setClientMsg(clientMsg);
                MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.S_XING_YOU_SHAN_SHUI_DICE_FROM_CROSS, respMsg));
                return;
            }

            refreshUserEnergy(userData, false);

            if(diceType == 1 || diceType == 4 || diceType == 5){
                dice = new Random().nextInt(6) + 1;
                if(diceType == 1){
                    //体力判断
                    if(userData.getEnergy() <= 0){
                        clientMsg.setRet(GameErrorCode.E_XING_YOU_SHAN_SHUI_ENERGY_NO_ENOUGH);
                        respMsg.setClientMsg(clientMsg);
                        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.S_XING_YOU_SHAN_SHUI_DICE_FROM_CROSS, respMsg));
                        return;
                    }
                }

            }else if(diceType == 2){
                XingYouShanShuiRoleInfo roleInfo = config.getRoleInfo(userData.getRoleId());
                if(roleInfo != null){
                    int i = new Random().nextInt(roleInfo.getDice().size());
                    dice = roleInfo.getDice().get(i);
                }
            }
            if(diceType == 4){
                if(userData.getDriftTimes() <= 0){
                    clientMsg.setRet(GameErrorCode.E_REQUEST_ARGUMENT_ERROR);
                    respMsg.setClientMsg(clientMsg);
                    MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.S_XING_YOU_SHAN_SHUI_DICE_FROM_CROSS, respMsg));
                    return;
                }
            }
            if(diceType == 5){
                //健步如飞次数
                if(userData.getFlyTimes() <= 0){
                    clientMsg.setRet(GameErrorCode.E_REQUEST_ARGUMENT_ERROR);
                    respMsg.setClientMsg(clientMsg);
                    MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.S_XING_YOU_SHAN_SHUI_DICE_FROM_CROSS, respMsg));
                    return;
                }
            }
            if(dice < 1){
                clientMsg.setRet(GameErrorCode.E_REQUEST_ARGUMENT_ERROR);
                respMsg.setClientMsg(clientMsg);
                MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.S_XING_YOU_SHAN_SHUI_DICE_FROM_CROSS, respMsg));
                return;
            }

            //处理逻辑
            int startPos = userData.getGridParam().getMapIndex();
            if(drift){
                startPos = userData.getDriftGridParam().getMapIndex();
            }
            DiceHandleResult result = new DiceHandleResult();
            result.setActivity(this);
            result.setConfig(config);
            result.setUserData(userData);
            result.setTongXingNum(tongXingNum);
            diceOnce(dice, startPos, result, diceType == 5);

            moveInfoBuilder.setDice(dice);
            moveInfoBuilder.setStartPosition(startPos);
            moveInfoBuilder.setPlayerId(userData.getUserId());

            if(result.getRet() != 0){
                clientMsg.setRet(result.getRet());
                respMsg.setClientMsg(clientMsg);
                respMsg.setSilverCoinTotal(userData.getSilverCoinTotal());
                MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.S_XING_YOU_SHAN_SHUI_DICE_FROM_CROSS, respMsg));
                return;
            }

            if(result.getGridHandleResultList().isEmpty()){
                return;
            }

            //开始处理结果
            LogCrossXingYouMove moveLog = new LogCrossXingYouMove(userData.getUserId(), userData.getActivityId(), userData.getTeamId(), userData.getMapTeamId());
            moveLog.setGroupId(this.groupId);
            moveLog.setStartPos(startPos);
            moveLog.setDice(dice);

            //汇总奖励
            ShanShuiGridParam lastShuiGridParam = null;
            XingYouShanShuiProto.ShanShuiEventInfo.Builder lastEventBuilder = null;

            //是否加圈数
            boolean addRound = false;

            for (int i = 0; i < result.getGridHandleResultList().size(); i++) {
                GridHandleResult handleResult = result.getGridHandleResultList().get(i);
                XingYouShanShuiProto.ShanShuiEventInfo.Builder eventBuilder = handleResult.getBuilder();
                if(eventBuilder != null){
                    if(eventBuilder.hasAward()){
                        property.addProperty(PropertyHelper.parseStringToProperty(eventBuilder.getAward()));
                    }
                    if(eventBuilder.getGridId() == eXingYouGridTypes.One.getId()){
                        addRound = true;
                    }
                    lastEventBuilder = eventBuilder;
                }
                lastShuiGridParam = handleResult.getGridParam();
            }
            if(lastShuiGridParam == null){
                return;
            }

            List<Integer> eventList = new ArrayList<>();
            moveLog.setRoleId(userData.getRoleId());
            moveLog.setEndPos(lastShuiGridParam.getMapIndex());
            boolean startShip = false;
            synchronized (getTeamLocker(userData.getTeamId())){
                //处理祈愿进度
                if(result.getAddWish() > 0){
                    WishGridHandler wishGridHandler = new WishGridHandler();
                    XingYouShanShuiProto.ShanShuiConfirmEventRsp.Builder resp = XingYouShanShuiProto.ShanShuiConfirmEventRsp.newBuilder();

                    ConfirmHandleResult handleResult = new ConfirmHandleResult();
                    handleResult.setActivity(this);
                    handleResult.setBuilder(resp);
                    handleResult.setEventTouch(true);
                    int add = Math.min(result.getAddWish(), 100 - teamData.getWishValue());
                    wishGridHandler.confirm(config.getGridInfo(eXingYouGridTypes.Thirteen.getId()), userData, handleResult, add, false);

                    if(handleResult.getRet() == 0){
                        CrossXingYouShanShuiTeamActionLogData logData = createActionLogData(result.getUserData(), XingYouShanShuiProto.ShanShuiLogTypeEnum.SHAN_SHUI_LOG_EVENT, PropertyHelper.parsePropertyToString(handleResult.getReward()),
                                Arrays.asList(String.valueOf(result.getUserData().getRoleId()), String.valueOf(9), String.valueOf(add)));
                        result.getActionLogDataList().add(logData);

                        property.addProperty(handleResult.getReward());
                    }else {
                        CrossXingYouShanShuiMgr.getLogger().info("活动 {} 玩家 {}，祈愿事件未执行 ", config.getActivityInfo().getActivityId(), userData.getUserId());
                    }
                }

                containSilver = property.getCountByGoodsId(config.getSHANSHUI_SILVER_COIN_ID()).compareTo(BigInteger.ZERO) > 0;
                moveLog.setReward(PropertyHelper.parsePropertyToString(property));
                moveLog.setSliverCoin(property.getCountByGoodsId(config.getSHANSHUI_SILVER_COIN_ID()).intValue());
                moveLog.setGoldCoin(property.getCountByGoodsId(config.getSHANSHUI_GOLD_COIN_ID()).intValue());
                addReward(userData, property, drift, 6);
                if(lastShuiGridParam.isDrift()){
                    userData.setDriftGridParam(lastShuiGridParam);
                }else {
                    userData.setGridParam(lastShuiGridParam);
                }
                if(diceType == 5){
                    userData.setFlyTimes(userData.getFlyTimes() - 1);
                }else if(diceType == 1){
                    userData.setEnergy(userData.getEnergy() - 1);
                }
                //累计消耗体力(普通骰子才算)
                if(diceType == 1){
                    userData.setUseEnergy(userData.getUseEnergy() + 1);
                    XingYouShanShuiGridInfo gridInfo = config.getGridInfo(eXingYouGridTypes.Twelve.getId());
                    if(gridInfo != null && getTeamTotalUseEnergy(userData.getTeamId()) == gridInfo.getParam().get(0)){
                        startShip = true;
                    }
                }
                //圈数
                if(addRound){
                    userData.setRound(1 + userData.getRound());
                }
                userData.getNotTouchGrid().remove(Integer.valueOf(lastShuiGridParam.getId()));

                if(lastShuiGridParam.getEventId() == 3){
                    userData.setFlyTimes(3);
                    XingYouShanShuiEventInfo eventInfo = config.getEventInfo(3);
                    if(eventInfo != null){
                        userData.setFlyTimes(eventInfo.getParam().get(0));
                    }
                }

                moveLog.setBuffInfo(getBuffString(userData, result.isInMazu()));
                if(diceType == 2){
                    moveLog.setUseItem(config.getSHANSHUI_EXCLUSIVE_DICE_ID() + "=1");
                }else if(diceType == 3){
                    moveLog.setUseItem(config.getSHANSHUI_MECHANICAL_DICE_ID() + "=1");
                }

                dealBuffTimes(userData, drift, result, lastShuiGridParam);

                moveLog.setBuffInfoNew(getBuffString(userData, result.isInMazu()));
            }

            //漂泊次数扣除及漂泊状态结算
            if(diceType == 4){
                if(userData.getDriftTimes() > 0){
                    userData.setDriftTimes(userData.getDriftTimes() - 1);
                    if(userData.getDriftTimes() == 0 && userData.getDriftEndType() >= -1){
                        userData.setDriftEndType(-3);
                        if(lastEventBuilder != null){
                            lastEventBuilder.setEventId(-3);
                            //不强制结束当前格子, 次数用尽，还是可以挑战等二次操作
//                            lastEventBuilder.setHandle(true);
                        }
                        lastShuiGridParam.setEventId(-3);
                        //不强制结束当前格子, 次数用尽，还是可以挑战等二次操作
//                        lastShuiGridParam.setHandled(true);
                    }
                }
            }

            //结算协助次数
            if(config.getSHANSHUI_HELP_RECOVER_TIME().size() == 2 && config.getSHANSHUI_HELP_RECOVER_TIME().get(0) > 0) {
                if (userData.getUseEnergy() % config.getSHANSHUI_HELP_RECOVER_TIME().get(0) == 0) {
                    userData.setHelpTimes(userData.getHelpTimes() + config.getSHANSHUI_HELP_RECOVER_TIME().get(1));
                }
            }

            //拼装返回结果
            moveInfoBuilder.setEndPosition(lastShuiGridParam.getMapIndex());
            for (int i = 0; i < result.getGridHandleResultList().size(); i++) {
                GridHandleResult handleResult = result.getGridHandleResultList().get(i);
                XingYouShanShuiProto.ShanShuiEventInfo.Builder eventBuilder = handleResult.getBuilder();
                if(eventBuilder != null){
                    moveInfoBuilder.addEventInfo(eventBuilder);
                    if(eventBuilder.getEventId() > 0){
                        eventList.add(eventBuilder.getEventId());
                    }
                }
            }

            if(startShip){
                CrossXingYouShanShuiTeamActionLogData logData = createActionLogData(userData, XingYouShanShuiProto.ShanShuiLogTypeEnum.SHAN_SHUI_LOG_PAINTED_PLEASURE_BOAT, "", "");
                result.getActionLogDataList().add(logData);
            }

            //处理事件日志
            for (CrossXingYouShanShuiTeamActionLogData logData : result.getActionLogDataList()) {
                addCrossXingYouShanShuiTeamActionLogData(logData);
            }

            //体力日志
            if(diceType == 1) {
                LogCrossXingYouEnergy logCrossXingYouEnergy = new LogCrossXingYouEnergy(userData.getUserId(), userData.getTeamId(), userData.getActivityId(), 1, 1, userData.getEnergy());
                logCrossXingYouEnergy.setGroupId(this.groupId);
                CrossAutoLogMgr.add(logCrossXingYouEnergy);
            }

            moveLog.setEventList(StringUtils.listToString(eventList, ","));

            CrossAutoLogMgr.add(moveLog);


            if(userData.getDriftEndType() == -1){
                respMsg.setUsePassIdNum(1);
                userData.setDriftEndType(0);
            }

            for (Object log : result.getAutoLogList()) {
                CrossAutoLogMgr.add(log);
            }
        }

        clientMsg.setRet(0);
        clientMsg.setMoveInfo(moveInfoBuilder);

        respMsg.setReward(PropertyHelper.parsePropertyToString(property));
        if(!drift) {
            XingYouShanShuiProto.ShanShuiPlayerInfo.Builder playerInfoBuilder = getPlayerInfoBuilder(userData);
            clientMsg.setPlayerInfo(playerInfoBuilder);
            //地图数据
            clientMsg.setMapInfo(getMapInfoBuilder(userData.getTeamId()));
        }else {
            int driftTeamId = driftMapTeamId > 0 ? driftMapTeamId : userData.getMapTeamId();
            if(driftTeamId > 0){
                clientMsg.setDriftInfo(getDriftInfo(driftTeamId, userData));
            }else {
                CrossXingYouShanShuiMgr.getLogger().info("同步地图数据异常  {}，{}", config.getActivityInfo().getActivityId(), userData.getUserId());
            }
        }

        respMsg.setRound(userData.getRound());
        respMsg.setUseEnergyTotal(userData.getUseEnergy());
        respMsg.setClientMsg(clientMsg);
        respMsg.setSilverCoinTotal(userData.getSilverCoinTotal());
        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.S_XING_YOU_SHAN_SHUI_DICE_FROM_CROSS, respMsg));

        //健步如飞日志
        replaceActionLogForEvent3(diceType, dice, userData);

        //体力使用同步
        syncTeamData(userData, true);

        if(containSilver){
            syncShanShuiPropNotify(userData.getTeamId(), Arrays.asList(XingYouShanShuiProto.PROP.TEAM_SILVER_VALUE, XingYouShanShuiProto.PROP.TEAM_CUL_SILVER_VALUE));
        }

        diceBroadcast(respMsg, clientMsg, userData, drift, driftMapTeamId);

        if(drift != userData.isDrift()){
            //开始漂泊通知
            syncDriftState(playerId, userData.getMapTeamId(), 1);
        }

        //同步下自己的红点
        needSyncRedDotUserMap.add(userData.getUserId());
    }

    private void replaceActionLogForEvent3(int diceType, int dice, CrossXingYouShanShuiUserData userData) {
        try {
            if (diceType == 5) {
                CrossXingYouShanShuiTeamActionLogData logData = createActionLogData(userData, XingYouShanShuiProto.ShanShuiLogTypeEnum.SHAN_SHUI_LOG_EVENT, "",
                        Arrays.asList(String.valueOf(userData.getRoleId()), String.valueOf(3), String.valueOf(dice), String.valueOf(userData.getGridParam().getId())));
                logData.setEventId(3);
                logData.setDrift(0);
                addCrossXingYouShanShuiTeamActionLogData(logData);
            }
        }catch (Exception e){
            CrossXingYouShanShuiMgr.getLogger().error("", e);
        }
    }

    /**
     * 移动后广播
     */
    private void diceBroadcast(XingYouShanShuiProto.CrossShanShuiDiceRsp.Builder respMsg, XingYouShanShuiProto.ShanShuiDiceRsp.Builder clientMsg, CrossXingYouShanShuiUserData userData, boolean drift, int driftMapTeamId) {
        //广播
        if(clientMsg.getRet() == 0){
            CommonTeam commonTeam = CommonTeamMgr.getTeam(config.getActivityInfo().getActivityId(), this.groupId, userData.getTeamId());
            List<Long> memberList = new ArrayList<>();
            if(commonTeam != null){
                for (Map.Entry<Long, CommonTeamUserData> entry : commonTeam.getMemberDataMap().entrySet()) {
                    if(entry.getKey() == userData.getUserId()){
                        continue;
                    }
                    memberList.add(entry.getKey());
                }
            }
            List<Long> driftMemberList = new ArrayList<>();
            if(userData.getMapTeamId() > 0){
                CrossXingYouShanShuiTeamData driftTeamData = getTeamData(userData.getMapTeamId());
                driftMemberList = new ArrayList<>(driftTeamData.getVisitorMap().keySet());
                driftMemberList.remove(userData.getUserId());
            }
            XingYouShanShuiProto.ShanShuiMoveInfo moveInfo = respMsg.getClientMsg().getMoveInfo();
            if(drift){
                //漂泊
                if(userData.isDrift()){
                    //漂泊中
                    //同步漂泊成员
                    syncDriftMoveInfo(userData.getMapTeamId(), driftMemberList, moveInfo);
                }else {
                    //漂泊结束
                    //同步队友
                    if(respMsg.getClientMsg().hasMapInfo()) {
                        syncMemberMove(memberList, moveInfo, respMsg.getClientMsg().getMapInfo());
                    }else {
                        syncMemberMove(memberList, moveInfo, getMapInfoBuilder(userData.getTeamId()).build());
                    }

                    //同步漂泊成员
                    syncDriftMoveInfo(driftMapTeamId, driftMemberList, moveInfo);
                }
            }else {
                if(userData.isDrift()){
                    //初始漂泊
                    //同步队友
                    if(respMsg.getClientMsg().hasMapInfo()) {
                        syncMemberMove(memberList, moveInfo, respMsg.getClientMsg().getMapInfo());
                    }else {
                        syncMemberMove(memberList, moveInfo, getMapInfoBuilder(userData.getTeamId()).build());
                    }

                    //同步漂泊成员
                    syncDriftMoveInfo(userData.getMapTeamId(), driftMemberList, moveInfo);
                }else {
                    //同步队友
                    if(respMsg.getClientMsg().hasMapInfo()) {
                        syncMemberMove(memberList, moveInfo, respMsg.getClientMsg().getMapInfo());
                    }else {
                        syncMemberMove(memberList, moveInfo, getMapInfoBuilder(userData.getTeamId()).build());
                    }
                }
            }
        }
    }

    /**
     * 处理buff消耗(非漂泊状态才扣)
     */
    private void dealBuffTimes(CrossXingYouShanShuiUserData userData, boolean drift, DiceHandleResult result, ShanShuiGridParam lastShuiGridParam) {
        if(!drift) {
            if (userData.getMisfortuneTimes() > 0) {
                userData.setMisfortuneTimes(userData.getMisfortuneTimes() - 1);
                //预留给二次确认
                if (!lastShuiGridParam.isHandled()) {
                    lastShuiGridParam.addUseBuf(12);
                }
            }
            if (userData.getLuckyTimes() > 0) {
                userData.setLuckyTimes(userData.getLuckyTimes() - 1);
                //预留给二次确认
                if (!lastShuiGridParam.isHandled()) {
                    lastShuiGridParam.addUseBuf(13);
                }
            }

            //处理buff获得
            int times = result.getBuffMap().getOrDefault(12, 0);
            if (times > 0) {
                userData.setMisfortuneTimes(times + userData.getMisfortuneTimes());
            }
            times = result.getBuffMap().getOrDefault(13, 0);
            if (times > 0) {
                userData.setLuckyTimes(times + userData.getLuckyTimes());
            }
        }
    }

    private String getBuffString(CrossXingYouShanShuiUserData userData, boolean inMazu) {
        StringBuilder builder = new StringBuilder();
        builder.append("12=").append(userData.getMisfortuneTimes()).append(",");
        builder.append("13=").append(userData.getLuckyTimes()).append(",");
        builder.append("0=").append(inMazu ? 1 : 0);
        return builder.toString();
    }

    public boolean tryCatch(int pos, CrossXingYouShanShuiUserData userData, DiceHandleResult result, GridHandleResult gridHandleResult){
        return tryCatch(pos, userData, result, gridHandleResult, false);
    }

    /**
     * 投骰子，尝试抓捕
     * 外部不可嵌套队伍锁
     */
    public boolean tryCatch(int pos, CrossXingYouShanShuiUserData userData, DiceHandleResult result, GridHandleResult gridHandleResult, boolean force) {
        int endType = -2;
        //漂泊状态，且未结束
        if(userData.isDrift() && userData.getDriftEndType() > -2) {
            if(userData.getMapTeamId() <= 0){
                CrossXingYouShanShuiMgr.getLogger().debug("活动{} 玩家{} 漂泊状态 重复触发抓捕", config.getActivityInfo().getActivityId(), userData.getUserId());
                return false;
            }
            CrossXingYouShanShuiTeamData teamData = result.getActivity().getTeamData(userData.getMapTeamId());
            if(teamData != null){
                if(teamData.getCaptorList().contains(pos) || force){
                    if(result.getTongXingNum() > 0){
                        result.setUseTongXing(true);
                        gridHandleResult.getBuilder().setEventId(-1);
                        userData.setDriftEndType(-1);
                    }else {
                        userData.setDriftEndType(endType);
                        //给客户端
                        gridHandleResult.getBuilder().setEventId(endType);
                        gridHandleResult.getBuilder().setHandle(true);
                        //覆盖玩家数据
                        gridHandleResult.getGridParam().setEventId(endType);
                        gridHandleResult.getGridParam().setHandled(true);
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * 抓捕，对方才有抓捕奖励
     */
    public Property catchSettle(CrossXingYouShanShuiUserData userData) {
        int mapTeamId = userData.getMapTeamId();
        //driftEndType : -5 超时, -4 到玉门关,-3 骰子用完，-2 被抓, -1 通行证道具
        boolean isCatch = userData.getDriftEndType() != -3;
        Property property = reBackFromDrift(userData, isCatch);
        if(mapTeamId > 0 && !property.isNothing()){
            CommonTeam team = CommonTeamMgr.getTeam(userData.getActivityId(), this.groupId, mapTeamId);
            if(team != null){
                CrossXingYouShanShuiTeamData teamData = getTeamData(mapTeamId);
                synchronized (getTeamLocker(mapTeamId)){
                    teamData.getCaptorReward().addProperty(property);
                }
                //被抓捕日志
                LogCrossXingYouYamen logData = new LogCrossXingYouYamen(userData.getActivityId(), userData.getTeamId(), userData.getUserId(), 3, mapTeamId, userData.getGridParam().getMapIndex(),
                        userData.getGridParam().getId(), 1, property.getCountByGoodsId(config.getSHANSHUI_SILVER_COIN_ID()).intValue(),
                        property.getCountByGoodsId(config.getSHANSHUI_GOLD_COIN_ID()).intValue());
                logData.setGroupId(this.groupId);
                CrossAutoLogMgr.add(logData);

                syncShanShuiPropNotify(mapTeamId, Collections.singletonList(XingYouShanShuiProto.PROP.YA_MEN_SILVER_VALUE));
            }
        }

        if(isCatch) {
            //抓捕日志
            CrossXingYouShanShuiCatchLogData catchLogData = new CrossXingYouShanShuiCatchLogData();
            catchLogData.setGroupId(this.groupId);
            catchLogData.setInsertOption();
            catchLogData.setActivityId(userData.getActivityId());
            catchLogData.setTeamId(userData.getMapTeamId());
            catchLogData.setTargetUserId(userData.getUserId());
            catchLogData.setTargetTeamId(userData.getTeamId());
            catchLogData.setCatchTime(System.currentTimeMillis());
            catchLogData.setNickName("");
            UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(userData.getUserId());
            if (userBaseInfo != null) {
                catchLogData.setNickName(userBaseInfo.getNickName());
            }
            catchLogData.setSeizeCount(PropertyHelper.parsePropertyToString(property));
            addCrossXingYouShanShuiCatchLogData(catchLogData);
        }
        return property;
    }

    /**
     * 漂泊返回
     * 返回被扣除的
     */
    public Property reBackFromDrift(CrossXingYouShanShuiUserData userData, boolean isCatch){
        //重置玩家数据
        userData.setDriftTimes(0);
        userData.setDriftEndType(0);
        Property driftReward = new Property();
        if(isCatch){
            XingYouShanShuiGridInfo gridInfo = config.getGridInfo(eXingYouGridTypes.Fourteen.getId());
            if(gridInfo != null){
                //先加
                driftReward.addProperty(userData.getDriftReward());
                BigDecimal divide2 = BigDecimal.valueOf(gridInfo.getParam().get(4)).divide(BigDecimal.valueOf(1000), 3, BigDecimal.ROUND_UP);
                driftReward.rideProperty(divide2);

                BigDecimal divide = BigDecimal.valueOf(1000 - gridInfo.getParam().get(4)).divide(BigDecimal.valueOf(1000), 3, BigDecimal.ROUND_UP);
                userData.getDriftReward().rideProperty(divide);
                userData.setUpdateOption();
            }
        }
        return driftReward;
    }

    /**
     * 掷骰子
     * @param dice 骰子数
     * @param startPos 起始位置
     * @param result 结果
     * @param fly 是否健步如飞
     */
    public void diceOnce(int dice, int startPos, DiceHandleResult result, boolean fly){
        //停留的位置
        int end = -1;
        //经过的位置
        List<Integer> posList = new ArrayList<>();
        //经过的格子id
        List<Integer> gridList = new ArrayList<>();
        List<Integer> curMap = config.getSHANSHUI_MAP();
        if(result.getUserData().isDrift()){
            curMap = config.getSHANSHUI_OTHER_MAP();
        }else if(inMazuTemp(result.getUserData())){
            curMap = config.getSHANSHUI_TOWER_MAP();
            result.setInMazu(true);
        }
        //清理上次缓存buf
        result.getUserData().getGridParam().getCacheBuf().clear();
        int star = startPos;
        for (int i = 1; i <= dice; i++) {
            end = star + 1;
            if(end > curMap.size() - 1){
                end = 0;
                star = 0;
            }else {
                star++;
            }
            posList.add(end);
            gridList.add(curMap.get(end));
        }
        for (int i = 0; i < posList.size(); i++) {
            int pos = posList.get(i);
            int gridId = gridList.get(i);
            XingYouShanShuiGridInfo gridInfo = config.getGridInfo(gridId);
            handleGrid(gridInfo, pos, gridId, end, fly, result);
        }
    }

    public void calRewardBuff(CrossXingYouShanShuiUserData userData, Property property, boolean inMazu, int roleAddition, boolean building){
        calRewardBuff(userData, property, inMazu, roleAddition, userData.getGridParam().containCacheBuf(13), userData.getGridParam().containCacheBuf(12), building);
    }

    public void calRewardBuff(CrossXingYouShanShuiUserData userData, Property property, boolean inMazu, int roleAddition){
        calRewardBuff(userData, property, inMazu, roleAddition, false);
    }
    /**
     * 奖励buff计算 (非漂泊状态才能用)
     * @param luck 13 吉星高照
     * @param misfortune 12 霉运缠身
     * @param inMazu 妈祖buf
     * @param roleAddition 角色buf
     */
    public void calRewardBuff(CrossXingYouShanShuiUserData userData, Property property, boolean inMazu, int roleAddition, boolean luck, boolean misfortune, boolean building){
        if(userData.isDrift()){
            return;
        }
        if(property.isNothing()){
            return;
        }
        int luckAdd = 0;
        int misfortuneSub = 0;
        if(userData.getLuckyTimes() > 0 || luck){
            luckAdd = 1000;
        }
        if(userData.getMisfortuneTimes() > 0 || misfortune){
            misfortuneSub = 500;
        }
        int maZuAddition = 0;
        if(inMazu){
            XingYouShanShuiGridInfo info = config.getGridInfo(eXingYouGridTypes.Fifteen.getId());
            if(info != null){
                maZuAddition = info.getParam().get(2);
            }
        }
        if(luckAdd > 0 || misfortuneSub > 0 || maZuAddition > 0 || roleAddition > 0) {
            int addition = luckAdd + roleAddition - misfortuneSub;
            if(building){
                //妈祖仅对建筑的银票有效果
                addition += maZuAddition;
            }
            List<Integer> keyList = new ArrayList<>(property.getGoods().keySet());
            for (int goodsId : keyList) {
                if(goodsId == config.getSHANSHUI_SILVER_COIN_ID()){
                    BigInteger newValue = new BigDecimal(property.getCountByGoodsId(goodsId)).multiply(BigDecimal.valueOf(1000 + addition)).
                            divide(BigDecimal.valueOf(1000), 0, BigDecimal.ROUND_UP).toBigInteger();
                    property.setGood(goodsId, newValue);
                }
                //妈祖仅对建筑的金页子有效果
                if(building && inMazu && goodsId == config.getSHANSHUI_GOLD_COIN_ID()){
                    BigInteger newValue = new BigDecimal(property.getCountByGoodsId(goodsId)).multiply(BigDecimal.valueOf(1000 + maZuAddition)).
                            divide(BigDecimal.valueOf(1000), 0, BigDecimal.ROUND_UP).toBigInteger();
                    property.setGood(goodsId, newValue);
                }
            }
        }
    }

    /**
     * 添加奖励
     */
    public void addReward(CrossXingYouShanShuiUserData userData, Property property, boolean drift, int way) {
        if(property.isNothing()){
            return;
        }
        if(drift){
            //漂泊状态，缓存银票和金页子
            userData.getDriftReward().addProperty(config.getSHANSHUI_SILVER_COIN_ID(), property.getCountByGoodsId(config.getSHANSHUI_SILVER_COIN_ID()));
            userData.getDriftReward().addProperty(config.getSHANSHUI_GOLD_COIN_ID(), property.getCountByGoodsId(config.getSHANSHUI_GOLD_COIN_ID()));
            property.removeProperty(config.getSHANSHUI_SILVER_COIN_ID());
            property.removeProperty(config.getSHANSHUI_GOLD_COIN_ID());
        }
        for (Map.Entry<Integer, BigInteger> entry : property.getGoods().entrySet()) {
            if(entry.getKey() == config.getSHANSHUI_SILVER_COIN_ID()){
                CrossXingYouShanShuiTeamData teamData = getTeamData(userData.getTeamId());
                synchronized (getTeamLocker(userData.getTeamId())){
                    //银票
                    long add = entry.getValue().longValue();
                    //累计只加
                    if(add > 0) {
                        userData.setSilverCoinTotal(userData.getSilverCoinTotal() + add);
                    }
                    teamData.setSilverCoin(teamData.getSilverCoin() + add);
                    if(add > 0) {
                        teamData.setSilverCoinTotal(teamData.getSilverCoinTotal() + add);
                    }

                    //银票日志(各事件分开记录)
                    LogCrossXingYouSlive logCrossXingYouSlive = new LogCrossXingYouSlive(teamData.getTeamId(), teamData.getActivityId(), userData.getUserId(), 1, add, teamData.getSilverCoin(), way);
                    logCrossXingYouSlive.setGroupId(this.groupId);
                    CrossAutoLogMgr.add(logCrossXingYouSlive);
                }
                changeTeamRank(userData.getTeamId());
            }else if(entry.getKey() == config.getSHANSHUI_WANDER_DICE_ID()){
                userData.setDriftTimes(5);
                XingYouShanShuiGridInfo gridInfo = config.getGridInfo(eXingYouGridTypes.Sixteen.getId());
                if(gridInfo != null){
                    userData.setDriftTimes(gridInfo.getParam().get(0));
                }
                userData.setStartDriftTime(System.currentTimeMillis());
                //初始漂泊银票
                userData.getDriftReward().addProperty(config.getSHANSHUI_SILVER_COIN_ID(), config.getSHANSHUI_OTHER_MAP_BASE_REWARD());
                //清空上次事件
                userData.getDriftGridParam().setEventId(0);
            }
        }
        property.removeProperty(config.getSHANSHUI_WANDER_DICE_ID());
    }

    /**
     * 处理格子
     * @param gridInfo 格子配置
     * @param pos 位置
     * @param gridId  格子id
     * @param endPos 结束位置
     * @param fly 是否健步如飞
     * @param result 结果
     */
    public void handleGrid(XingYouShanShuiGridInfo gridInfo, int pos, int gridId, int endPos, boolean fly, DiceHandleResult result) {
        IXingYouGridHandler handler = CrossXingYouShanShuiMgr.getIXingYouGridHandler(gridId);
        if(handler != null){
            handler.handle(gridInfo, pos, gridId, endPos, fly, result);
        }
    }

    /**
     * 使用道具恢复体力
     */
    public XingYouShanShuiProto.ShanShuiRecoverEnergyRsp.Builder recoverEnergy(long playerId, int num) {
        XingYouShanShuiProto.ShanShuiRecoverEnergyRsp.Builder respMsg = XingYouShanShuiProto.ShanShuiRecoverEnergyRsp.newBuilder();
        respMsg.setUseNum(num);
        CrossXingYouShanShuiUserData userData = getUserData(playerId);

        //仅防止自己并发
        synchronized (getUserLocker(userData.getUserId())) {
            refreshUserEnergy(userData, true);
            userData.setEnergy(userData.getEnergy() + (num * config.getSHANSHUI_TIPS_NUM()));
            LogCrossXingYouEnergy logCrossXingYouEnergy = new LogCrossXingYouEnergy(userData.getUserId(), userData.getTeamId(), userData.getActivityId(), 2, num * config.getSHANSHUI_TIPS_NUM(), userData.getEnergy());
            logCrossXingYouEnergy.setGroupId(this.groupId);
            CrossAutoLogMgr.add(logCrossXingYouEnergy);
        }
        respMsg.setEnergy(userData.getEnergy());
        respMsg.setEnergyRecoverTime(userData.getEnergyLastTime());
        respMsg.setRet(0);
        needSyncRedDotUserMap.add(playerId);
        return respMsg;
    }

    /**
     * 刷新玩家体力
     */
    public void refreshUserEnergy(CrossXingYouShanShuiUserData user, boolean forceUpdate){
        long now = System.currentTimeMillis() / 1000;
        long time = now - user.getEnergyLastTime();
        if (user.getEnergy() < config.getSHANSHUI_DICE_INITIAL_NUM()) {
            int timesCD = (int)(time / config.getSHANSHUI_DICE_RECOVER_TIME());
            if (timesCD > 0 ) {
                int times = timesCD;
                if (times + user.getEnergy() < config.getSHANSHUI_DICE_INITIAL_NUM()) {
                    user.setEnergyLastTime(user.getEnergyLastTime() + timesCD * config.getSHANSHUI_DICE_RECOVER_TIME());
                    user.setEnergy(user.getEnergy() + times);
                }else {
                    user.setEnergyLastTime(now);
                    user.setEnergy(config.getSHANSHUI_DICE_INITIAL_NUM());
                }
            }
        } else {
            if (forceUpdate) {
                user.setEnergyLastTime(now);
            }
        }

    }

    /**
     * 角色分配
     */
    public XingYouShanShuiProto.ShanShuiRoleAssignmentRsp.Builder roleAssignment(long playerId, XingYouShanShuiProto.ShanShuiRoleAssignmentReq reqMsg) {
        XingYouShanShuiProto.ShanShuiRoleAssignmentRsp.Builder clientMsg = XingYouShanShuiProto.ShanShuiRoleAssignmentRsp.newBuilder();
        clientMsg.setRet(0);

        CommonTeamActivity teamActivity = CommonTeamMgr.getActivity(config.getActivityInfo().getActivityId(), this.groupId);
        if(teamActivity == null){
            clientMsg.setRet(GameErrorCode.E_COMMON_TEAM_TEAM_ACTIVITY_NOT_EXIST);
            return clientMsg;
        }

        CrossXingYouShanShuiUserData userData = getUserData(playerId);

        CommonTeam team = teamActivity.getTeam(userData.getTeamId());
        if(team == null){
            clientMsg.setRet(GameErrorCode.E_COMMON_TEAM_TEAM_NOT_EXIST);
            return clientMsg;
        }
        synchronized (getTeamLocker(userData.getTeamId())){
            if(team.getLeaderId() != userData.getUserId()){
                clientMsg.setRet(GameErrorCode.E_XING_YOU_SHAN_SHUI_TEAM_LEADER_LIMIT);
                return clientMsg;
            }
            Set<Integer> roleSet = new HashSet<>();
            for (int i = 0; i < reqMsg.getPlayerIdCount(); i++) {
                int roleId = reqMsg.getRoleId(i);
                roleSet.add(roleId);
            }
            if(roleSet.size() != reqMsg.getPlayerIdCount()){
                clientMsg.setRet(GameErrorCode.E_REQUEST_ARGUMENT_ERROR);
                return clientMsg;
            }
            for (int i = 0; i < reqMsg.getPlayerIdCount(); i++) {
                long uid = reqMsg.getPlayerId(i);
                int roleId = reqMsg.getRoleId(i);
                if(roleId == 0){
                    continue;
                }
                XingYouShanShuiRoleInfo roleInfo = config.getRoleInfo(roleId);
                if(!"0".equals(roleInfo.getPrice()) && !userData.getBuyRole().contains(roleId)){
                    clientMsg.setRet(GameErrorCode.E_XING_YOU_SHAN_SHUI_ROLE_CLOSE);
                    return clientMsg;
                }
                if(team.getMemberDataMap().containsKey(uid)){
                    CrossXingYouShanShuiUserData data = getUserData(uid);
                    if(data.getTeamId() == team.getTeamId()){
                        data.setRoleId(roleId);
                        CommonTeamUserData teamUserData = teamActivity.getUserData(uid);
                        if(teamUserData != null){
                            teamUserData.setExtendsParam(String.valueOf(data.getRoleId()));
                        }
                    }
                }
                //日志
                LogCrossXingYouRoleChange logCrossXingYouRoleChange = new LogCrossXingYouRoleChange(config.getActivityInfo().getActivityId(), team.getTeamId(), team.getLeaderId(), uid, roleId);
                logCrossXingYouRoleChange.setGroupId(this.groupId);
                CrossAutoLogMgr.add(logCrossXingYouRoleChange);
            }
        }
        return clientMsg;
    }

    /**
     * 二次确认
     */
    public int confirmByCmd(long serverId, long playerId, int gridId, long indexId, boolean isDrift) {

        CrossXingYouShanShuiUserData userData = getUserData(playerId);
        XingYouShanShuiProto.ShanShuiConfirmEventRsp.Builder resp = XingYouShanShuiProto.ShanShuiConfirmEventRsp.newBuilder();
        ConfirmHandleResult handleResult = new ConfirmHandleResult();
        int eventId = 0;
        synchronized (getUserLocker(userData.getUserId())){

            ShanShuiGridParam gridParam = userData.getGridParam();
            if(userData.isDrift()){
                gridParam = userData.getDriftGridParam();
            }
            if(gridParam == null || gridParam.getId() != gridId || gridParam.isHandled()){
                //参数问题
                return GameErrorCode.E_XING_YOU_SHAN_SHUI_GRID_HANDLED;
            }
            XingYouShanShuiGridInfo gridInfo = config.getGridInfo(gridId);
            if(gridInfo == null){
                return GameErrorCode.E_REQUEST_ARGUMENT_ERROR;
            }

            IXingYouGridHandler gridHandler = CrossXingYouShanShuiMgr.getIXingYouGridHandler(gridId);
            if(gridHandler == null){
                return GameErrorCode.E_REQUEST_ARGUMENT_ERROR;
            }

            if(gridParam.isHandled()){
                return GameErrorCode.E_XING_YOU_SHAN_SHUI_GRID_HANDLED;
            }

            if(gridParam.getId() != gridInfo.getId()){
                return GameErrorCode.E_REQUEST_ARGUMENT_ERROR;
            }

            eventId = gridParam.getEventId();

            handleResult.setActivity(this);
            handleResult.setBuilder(resp);
            gridHandler.confirm(gridInfo, userData, handleResult, indexId, isDrift);

            if(handleResult.getRet() != 0){
                return handleResult.getRet();
            }

            //处理事件日志
            for (CrossXingYouShanShuiTeamActionLogData logData : handleResult.getActionLogDataList()) {
                addCrossXingYouShanShuiTeamActionLogData(logData);
            }

            for (Object log : handleResult.getAutoLogList()) {
                CrossAutoLogMgr.add(log);
            }
            resp.setSliverCoin(handleResult.getReward().getCountByGoodsId(config.getSHANSHUI_SILVER_COIN_ID()).intValue());
            //二次确认先设置返回奖励
            resp.setAward(PropertyHelper.parsePropertyToString(handleResult.getReward()));
            addReward(userData, handleResult.getReward(), userData.isDrift(), 8);
        }
        resp.setRet(0);
//        resp.setMapInfo(getMapInfoBuilder(userData.getTeamId()));

        XingYouShanShuiProto.ShanShuiMapInfo.Builder mapInfoBuilder = getMapInfoBuilder(userData.getTeamId());
        if(mapInfoBuilder != null) {
            resp.setMapInfo(mapInfoBuilder);
        }

        if(eventId == 2){
            resp.setRound(userData.getRound());
        }
//        if(userData.isDrift())
        resp.setDrift(userData.isDrift());
        if(userData.isDrift()){
            XingYouShanShuiProto.ShanShuiDriftInfo.Builder driftInfo = getDriftInfo(userData.getMapTeamId(), userData);
            if(driftInfo != null){
                resp.setDriftInfo(driftInfo.build());
            }
        }

        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.S_XING_YOU_SHAN_SHUI_CONFIRM_EVENT_FROM_CROSS, resp));

        syncShanShuiPropNotify(userData.getTeamId(), Arrays.asList(XingYouShanShuiProto.PROP.TEAM_SILVER_VALUE, XingYouShanShuiProto.PROP.TEAM_CUL_SILVER_VALUE));

        //需要同步移动
        if(eventId == 2 && handleResult.getMoveInfoBuilder() != null){
            CommonTeam commonTeam = CommonTeamMgr.getTeam(config.getActivityInfo().getActivityId(), this.groupId, userData.getTeamId());
            List<Long> memberList = new ArrayList<>();
            if(commonTeam != null){
                for (Map.Entry<Long, CommonTeamUserData> entry : commonTeam.getMemberDataMap().entrySet()) {
                    if(entry.getKey() == userData.getUserId()){
                        continue;
                    }
                    memberList.add(entry.getKey());
                }
            }
//            XingYouShanShuiProto.ShanShuiMapInfo.Builder builder = getMapInfoBuilder(userData.getTeamId());
            if(mapInfoBuilder != null) {
                syncMemberMove(memberList, handleResult.getMoveInfoBuilder().build(), mapInfoBuilder.build());
            }
        }

        //同步下银票(临时热更处理)
        XingYouShanShuiProto.CrossShanShuiEnterMapRsp.Builder crossRsp = XingYouShanShuiProto.CrossShanShuiEnterMapRsp.newBuilder();
        XingYouShanShuiProto.ShanShuiEnterMapRsp.Builder respMsg = XingYouShanShuiProto.ShanShuiEnterMapRsp.newBuilder();
        respMsg.setRet(-10);
        crossRsp.setRsp(respMsg);
        crossRsp.setSilverCoinTotal(userData.getSilverCoinTotal());
        crossRsp.setRound(userData.getRound());
        crossRsp.setUseEnergyTotal(userData.getUseEnergy());
        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.S_XING_YOU_SHAN_SHUI_ENTER_MAP_FROM_CROSS, crossRsp));
        return 0;
    }

    public List<Integer> randomTeam(CrossXingYouShanShuiTeamData teamData) {
        int size = 10 - teamData.getRandomTodayTeam().size();
        if(size <= 0){
            return Collections.emptyList();
        }
        List<Integer> list = new ArrayList<>(teamData.getTodayTeam());
        list.addAll(teamData.getRandomTodayTeam());
        return getRandomTemList(teamData, size, list);
    }

    private List<Integer> getRandomTemList(CrossXingYouShanShuiTeamData teamData, int size, List<Integer> list) {
        CommonTeamActivity activity = CommonTeamMgr.getActivity(config.getActivityInfo().getActivityId(), this.groupId);
        CommonTeam team = activity.getTeam(teamData.getTeamId());
        if(team == null){
            return Collections.emptyList();
        }
        UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(team.getLeaderId());
        if(userBaseInfo == null){
            return Collections.emptyList();
        }
        List<Integer> poolList = new ArrayList<>();
        List<Integer> result = new ArrayList<>();
        for (Map.Entry<Integer, CommonTeam> entry : activity.getTeamMap().entrySet()) {
            if(entry.getKey() == teamData.getTeamId()){
                continue;
            }
            if(list.contains(entry.getKey())){
                continue;
            }
            if(StringUtils.isNullOrEmpty(userBaseInfo.getUnionUid())){
                poolList.add(entry.getKey());
                continue;
            }
            UserBaseInfo info = CrossUserMgr.getUserBaseInfo(entry.getValue().getLeaderId());
            if(info == null){
                continue;
            }
            if(Objects.equals(info.getUnionUid(), userBaseInfo.getUnionUid())){
                continue;
            }
            CrossXingYouShanShuiTeamData targetTeam = getTeamData(entry.getKey());
            //队伍限制
            if(targetTeam != null && targetTeam.getVisitorMap().size() >= config.getSHANSHUI_MAP_NUM_LIMIT()){
                continue;
            }
            poolList.add(entry.getKey());
        }
        Random random = new Random();
        while (size > 0 && poolList.size() > 0){
            size--;
            int teamId = poolList.remove(random.nextInt(poolList.size()));
            result.add(teamId);
        }
        return result;
    }

    private String calUserRedValue(long userId) {
        CrossXingYouShanShuiUserData userData = getUserData(userId);
        int teamId = userData.getTeamId();
        if(teamId <= 0){
            return "0";
        }
        CrossXingYouShanShuiTeamData teamData = getTeamData(teamId);
        BigInteger red = BigInteger.ZERO;
        //体力(客户端算)
        if(userData.getEnergy() >= config.getSHANSHUI_DICE_INITIAL_NUM()){
            red = red.add(BigInteger.valueOf(2).pow(XingYouShanShuiProto.ShanShuiRedPointEnum.SHAN_SHUI_RED_POINT_ENERGY_FULL_VALUE));
        }
        //祈愿轮次奖励
        List<CrossXingYouShanShuiWishRewardData> roundRewardMap = teamWishRewardMap.get(teamId);
        if(roundRewardMap != null){
            boolean toGet = false;
            for (int i = 0; i < roundRewardMap.size(); i++) {
                CrossXingYouShanShuiWishRewardData rewardData = roundRewardMap.get(i);
                if(!rewardData.getRewardMap().containsKey(userId)){
                    toGet = true;
                    break;
                }
            }
            if(toGet){
                red = red.add(BigInteger.valueOf(2).pow(XingYouShanShuiProto.ShanShuiRedPointEnum.SHAN_SHUI_RED_POINT_TRADE_SHIP_ROUND_REWARD_VALUE));
            }
        }
        //祈愿分享奖励
        if(userData.getWishShareValue() > 0){
            red = red.add(BigInteger.valueOf(2).pow(XingYouShanShuiProto.ShanShuiRedPointEnum.SHAN_SHUI_RED_POINT_TRADE_SHIP_SHARE_REWARD_VALUE));
        }
        //协助列表
        List<CrossXingYouTargetMarkData> list = getTodoMarkDataList(userData);
        if(!list.isEmpty()) {
            boolean todo = false;
            CommonTeam team = CommonTeamMgr.getTeam(config.getActivityInfo().getActivityId(), this.groupId, userData.getTeamId());
            if(team != null){
                int memberCount = team.getMemberDataMap().size();
                for (CrossXingYouTargetMarkData markData : list) {
                    //我的，等他人处理
                    if(markData.getUserId() == userData.getUserId() && markData.getTzList().size() < memberCount - 1){
                        continue;
                    }
                    //未挑战
                    if(markData.getUserId() != userData.getUserId() && !markData.getTzList().contains(userData.getUserId()) && markData.getTargetHp() > 0){
                        //但是没次数
                        if(userData.getHelpTimes() <= 0){
                            continue;
                        }
                    }
                    todo = true;
                    break;
                }
            }
            if(todo) {
                red = red.add(BigInteger.valueOf(2).pow(XingYouShanShuiProto.ShanShuiRedPointEnum.SHAN_SHUI_RED_CAN_HELP_VALUE));
            }
        }
        //衙门收益（展示）
        if(userData.getCaptorReward() != null && !userData.getCaptorReward().isNothing()){
            red = red.add(BigInteger.valueOf(2).pow(XingYouShanShuiProto.ShanShuiRedPointEnum.SHAN_SHUI_RED_YA_MEN_REWARD_VALUE));
        }

        return red.toString();
    }

    public List<CrossXingYouTargetMarkData> getTodoMarkDataList(CrossXingYouShanShuiUserData userData){
        List<CrossXingYouTargetMarkData> markDataList = teamMarkMap.get(userData.getTeamId());
        if(markDataList == null){
            return Collections.emptyList();
        }
        CommonTeam team = CommonTeamMgr.getTeam(config.getActivityInfo().getActivityId(), this.groupId, userData.getTeamId());
        if(team == null){
            return Collections.emptyList();
        }
        int memberCount = team.getMemberDataMap().size();
        int currentSecond = DateHelper.getCurrentSecond();
        List<CrossXingYouTargetMarkData> list = new ArrayList<>();
        for (int i = 0; i < markDataList.size(); i++) {
            CrossXingYouTargetMarkData markData = markDataList.get(i);
            //已领奖
            if(markData.getGetReward() == 1){
                continue;
            }
            //待领取
            if(markData.getUserId() == userData.getUserId() && markData.getTargetHp() <= 0 && markData.getGetReward() == 0){
                list.add(markData);
                continue;
            }
            //已过期
            if (markData.getExpireTime() <= currentSecond){
                continue;
            }
            //未挑战
            if(markData.getUserId() != userData.getUserId() && !markData.getTzList().contains(userData.getUserId()) && markData.getTargetHp() > 0){
                list.add(markData);
            }
            //我的，等他人处理
            if(markData.getUserId() == userData.getUserId() && markData.getTzList().size() < memberCount - 1){
                list.add(markData);
            }
        }
        return list;
    }

    public int randomRoleId(int teamId){
        Random random = new Random();
        List<XingYouShanShuiRoleInfo> roleInfoList = new ArrayList<>();
        CommonTeam team = CommonTeamMgr.getTeam(config.getActivityInfo().getActivityId(), this.groupId, teamId);
        if(team == null){
            return 0;
        }
        List<Integer> list = new ArrayList<>();
        for (Map.Entry<Long, CommonTeamUserData> entry : team.getMemberDataMap().entrySet()) {
            CrossXingYouShanShuiUserData userData = getUserData(entry.getKey());
            if(userData.getRoleId() > 0) {
                list.add(userData.getRoleId());
            }
        }
        CrossXingYouShanShuiUserData teamUserData = getUserData(team.getLeaderId());
        for (XingYouShanShuiRoleInfo roleInfo : config.getRoleInfoList()) {
            if(list.contains(roleInfo.getId())){
                continue;
            }
            if("0".equals(roleInfo.getPrice())){
                roleInfoList.add(roleInfo);
            }else {
                if(teamUserData != null && teamUserData.getBuyRole().contains(roleInfo.getId())){
                    roleInfoList.add(roleInfo);
                }
            }
        }
        if(roleInfoList.isEmpty()){
            return 0;
        }
        int i = random.nextInt(roleInfoList.size());
        XingYouShanShuiRoleInfo roleInfo = roleInfoList.get(i);
        return roleInfo.getId();
    }

    /**
     * 建筑升级
     * @param itemId 道具id
     * @param num 道具数量
     * @param lv 当前等级
     */
    public int buildingUp(long serverId, long playerId, int position, int itemId, int num, int lv) {
        CrossXingYouShanShuiUserData userData = getUserData(playerId);
        if(userData.getTeamId() <= 0){
            return GameErrorCode.E_XING_YOU_SHAN_SHUI_PLAYER_NO_TEAM;
        }
        if(userData.isDrift()){
            return GameErrorCode.E_XING_YOU_SHAN_SHUI_ACTION_LIMIT_DRIFT;
        }

        XingYouShanShuiProto.ShanShuiUseItemRsp.Builder clientMsg = XingYouShanShuiProto.ShanShuiUseItemRsp.newBuilder();
        clientMsg.setRet(0);

        CrossXingYouShanShuiTeamMapData data;
        CrossXingYouShanShuiTeamData teamData = getTeamData(userData.getTeamId());

        XingYouShanShuiProto.CrossShanShuiUseItemRsp.Builder rsp = XingYouShanShuiProto.CrossShanShuiUseItemRsp.newBuilder();
        if(num > 0 && itemId > 0){
            Integer gid = config.getSHANSHUI_MAP().get(position);
            XingYouShanShuiGridInfo gridParam = config.getGridInfo(gid);
            if(gridParam.getType() != 2){
                clientMsg.setRet(GameErrorCode.E_XING_YOU_SHAN_SHUI_INFO_OUT_TIME);
                rsp.setClientMsg(clientMsg);
                MessageHelper.sendPacket(Protocol.S_XING_YOU_SHAN_SHUI_USE_ITEM_FROM_CROSS, rsp, userData.getUserId());
                return 0;
            }

            rsp.setConsume(itemId + "=" + num);

            data = getCrossXingYouShanShuiTeamMapData(userData.getTeamId(), position);
            XingYouShanShuiGridInfo gridInfo = config.getGridInfo(data.getGridId());
            if(itemId == config.getSHANSHUI_RED_ENVELOPE_ID()){

                synchronized (getTeamLocker(userData.getTeamId())) {
                    //开工
                    if (data.getCloseTimes() <= 0) {
                        //未闭园
                        clientMsg.setRet(GameErrorCode.E_XING_YOU_SHAN_SHUI_BUILDING_NO_CLOSE);
                        rsp.setClientMsg(clientMsg);
                        MessageHelper.sendPacket(Protocol.S_XING_YOU_SHAN_SHUI_USE_ITEM_FROM_CROSS, rsp, userData.getUserId());
                        return 0;
                    }
                    if(data.getCloseTimes() < num){
                        clientMsg.setRet(GameErrorCode.E_XING_YOU_SHAN_SHUI_INFO_OUT_TIME);
                        rsp.setClientMsg(clientMsg);
                        MessageHelper.sendPacket(Protocol.S_XING_YOU_SHAN_SHUI_USE_ITEM_FROM_CROSS, rsp, userData.getUserId());
                        return 0;
                    }
                    int closeTimes = data.getCloseTimes();
                    data.setCloseTimes(0);

                    LogCrossXingYouBuilding logData = new LogCrossXingYouBuilding(userData.getActivityId(), userData.getTeamId(), userData.getUserId(),
                            data.getMapIndex(), gridInfo.getId(), 3, userData.getTeamId(), closeTimes, data.getCloseTimes());
                    CrossAutoLogMgr.add(logData);

                }
                //同步闭园状态
                syncShanShuiPropNotify(userData.getTeamId(), Collections.singletonList(data.getGridId()));
            }else if(itemId == config.getSHANSHUI_EXPANSION_PLAN_ID()){

                int buildLv = data.getBuildLv();
                synchronized (getTeamLocker(userData.getTeamId())){
                    //是否全部建筑满级
                    boolean allTopLv = isTeamBuildAllTop(userData);
                    if(allTopLv){
                        Property property = PropertyHelper.parseStringToProperty(config.getSHANSHUI_EXPANSION_PLAN_RECYCLE());
                        property.rideProperty(num);
                        if(property.isNothing()){
                            clientMsg.setRet(GameErrorCode.E_REQUEST_ARGUMENT_ERROR);
                            rsp.setClientMsg(clientMsg);
                            MessageHelper.sendPacket(Protocol.S_XING_YOU_SHAN_SHUI_USE_ITEM_FROM_CROSS, rsp, userData.getUserId());
                            return 0;
                        }
                        clientMsg.setAward(PropertyHelper.parsePropertyToString(property));
                    }else {
                        //扩展图
                        if(num > 1){
                            clientMsg.setRet(GameErrorCode.E_REQUEST_ARGUMENT_ERROR);
                            rsp.setClientMsg(clientMsg);
                            MessageHelper.sendPacket(Protocol.S_XING_YOU_SHAN_SHUI_USE_ITEM_FROM_CROSS, rsp, userData.getUserId());
                            return 0;
                        }
                        if(data.getBuildLv() == 0){
                            clientMsg.setRet(GameErrorCode.E_XING_YOU_SHAN_SHUI_BUILDING_NO_BUILD);
                            rsp.setClientMsg(clientMsg);
                            MessageHelper.sendPacket(Protocol.S_XING_YOU_SHAN_SHUI_USE_ITEM_FROM_CROSS, rsp, userData.getUserId());
                            return 0;
                        }

                        if(data.getBuildLv() >= gridInfo.getParam().get(2)){
                            clientMsg.setRet(GameErrorCode.E_XING_YOU_SHAN_SHUI_BUILD_MAX_LEVEL);
                            rsp.setClientMsg(clientMsg);
                            MessageHelper.sendPacket(Protocol.S_XING_YOU_SHAN_SHUI_USE_ITEM_FROM_CROSS, rsp, userData.getUserId());
                            return 0;
                        }
                        data.setBuildLv(data.getBuildLv() + 1);
                        CrossXingYouShanShuiBuildingLogData buildingLogData = getCrossXingYouShanShuiBuildingLogData(userData, position, gid, buildLv);
                        addCrossXingYouShanShuiBuildingLogData(buildingLogData);

                        CrossXingYouShanShuiTeamActionLogData actionLogData = createActionLogData(userData, XingYouShanShuiProto.ShanShuiLogTypeEnum.SHAN_SHUI_LOG_BUILD_BUILDING,
                                "", Arrays.asList(String.valueOf(userData.getRoleId()), config.getSHANSHUI_EXPANSION_PLAN_ID() + "=1", String.valueOf(gridInfo.getId())));
                        addCrossXingYouShanShuiTeamActionLogData(actionLogData);

                        LogCrossXingYouBuildingUpgrade logData = new LogCrossXingYouBuildingUpgrade(userData.getActivityId(), userData.getTeamId(), userData.getUserId(), position, gid, 0, config.getSHANSHUI_EXPANSION_PLAN_ID() + "=1", data.getBuildLv());
                        logData.setGroupId(this.groupId);
                        CrossAutoLogMgr.add(logData);
                    }
                }
            }
        }else {
            ShanShuiGridParam dataGridParam = userData.getGridParam();
            if(dataGridParam == null || dataGridParam.isHandled()){
                return GameErrorCode.E_XING_YOU_SHAN_SHUI_HELP_DONE;
            }
            Integer gid = config.getSHANSHUI_MAP().get(dataGridParam.getMapIndex());
            XingYouShanShuiGridInfo gridParam = config.getGridInfo(gid);
            if(gridParam.getType() != 2 || gid != dataGridParam.getId()){
                return GameErrorCode.E_XING_YOU_SHAN_SHUI_HELP_DONE;
            }
            data = getCrossXingYouShanShuiTeamMapData(userData.getTeamId(), dataGridParam.getMapIndex());
            XingYouShanShuiGridInfo gridInfo = config.getGridInfo(data.getGridId());
            if(gridInfo == null || gridInfo.getType() != 2){
                return GameErrorCode.E_XING_YOU_SHAN_SHUI_HELP_DONE;
            }

            int buildLv;
            int consume;
            synchronized (getTeamLocker(userData.getTeamId())){
                //是否满级
                int maxLv = gridInfo.getParam().get(2);
                if(maxLv <= data.getBuildLv()){
                    return GameErrorCode.E_XING_YOU_SHAN_SHUI_BUILD_MAX_LEVEL;
                }
                buildLv= data.getBuildLv();
                if(buildLv != lv){
                    return GameErrorCode.E_XING_YOU_SHAN_SHUI_INFO_OUT_TIME;
                }
                consume = gridInfo.getParam().get(0);
                if(data.getBuildLv() > 0){
                    consume = gridInfo.getParam().get(1);
                }
                if(teamData.getSilverCoin() < consume){
                    return GameErrorCode.E_XING_YOU_SHAN_SHUI_SILVER_NO_ENOUGH;
                }
                teamData.setSilverCoin(teamData.getSilverCoin() - consume);
                userData.getGridParam().setHandled(true);
                data.setBuildLv(1 + data.getBuildLv());
                data.setUpdateTime(System.currentTimeMillis() / 1000);

                //日志
                LogCrossXingYouSlive logCrossXingYouSlive = new LogCrossXingYouSlive(teamData.getTeamId(), teamData.getActivityId(), userData.getUserId(), 2, consume, teamData.getSilverCoin(), 1);
                logCrossXingYouSlive.setGroupId(this.groupId);
                CrossAutoLogMgr.add(logCrossXingYouSlive);

                LogCrossXingYouBuildingUpgrade logData = new LogCrossXingYouBuildingUpgrade(userData.getActivityId(), userData.getTeamId(), userData.getUserId(), dataGridParam.getMapIndex(), gid, consume, "", data.getBuildLv());
                logData.setGroupId(this.groupId);
                CrossAutoLogMgr.add(logData);
            }
            CrossXingYouShanShuiBuildingLogData buildingLogData = getCrossXingYouShanShuiBuildingLogData(userData, dataGridParam.getMapIndex(), gid, buildLv);
            addCrossXingYouShanShuiBuildingLogData(buildingLogData);

            if(buildLv == 0){
                //修缮
                CrossXingYouShanShuiTeamActionLogData actionLogData = createActionLogData(userData, XingYouShanShuiProto.ShanShuiLogTypeEnum.SHAN_SHUI_LOG_BUILD_BUILDING,
                        "", Arrays.asList(String.valueOf(userData.getRoleId()), config.getSHANSHUI_SILVER_COIN_ID() + "=" + consume, String.valueOf(gridInfo.getId())));
                addCrossXingYouShanShuiTeamActionLogData(actionLogData);
            }else {
                //升级
                CrossXingYouShanShuiTeamActionLogData actionLogData = createActionLogData(userData, XingYouShanShuiProto.ShanShuiLogTypeEnum.SHAN_SHUI_LOG_UPGRADE_BUILDING,
                        "", Arrays.asList(String.valueOf(userData.getRoleId()), config.getSHANSHUI_SILVER_COIN_ID() + "=" + consume, String.valueOf(gridInfo.getId()), String.valueOf(buildLv + 1)));
                addCrossXingYouShanShuiTeamActionLogData(actionLogData);
            }
        }

        clientMsg.setRet(0);
        clientMsg.setUpdateTime(data.getUpdateTime());
        XingYouShanShuiProto.ShanShuiBuildingInfo.Builder builder = XingYouShanShuiProto.ShanShuiBuildingInfo.newBuilder();
        builder.setBuildingLevel(data.getBuildLv());
        builder.setBuildingState(data.getCloseTimes());
        builder.setPosition(userData.getGridParam().getMapIndex());
        builder.setGridId(data.getGridId());
        clientMsg.setBuildingInfo(builder);

        if(num > 0 && itemId > 0){
            rsp.setClientMsg(clientMsg);
            MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.S_XING_YOU_SHAN_SHUI_USE_ITEM_FROM_CROSS, rsp));
        }else {
            MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_XING_YOU_SHAN_SHUI_USE_ITEM, clientMsg));
            syncShanShuiPropNotify(userData.getTeamId(), Arrays.asList(XingYouShanShuiProto.PROP.TEAM_SILVER_VALUE, XingYouShanShuiProto.PROP.TEAM_CUL_SILVER_VALUE));
        }
        return 0;
    }

    /**
     * 队伍建筑是否都满级
     */
    private boolean isTeamBuildAllTop(CrossXingYouShanShuiUserData userData) {
        boolean allTopLv = true;
        Map<Integer, CrossXingYouShanShuiTeamMapData> mapDataMap = getCrossXingYouShanShuiTeamMapData(userData.getTeamId());
        //建筑数量
        int buildNum = 0;
        for (int i = 0; i < config.getSHANSHUI_MAP().size(); i++) {
            Integer gid = config.getSHANSHUI_MAP().get(i);
            XingYouShanShuiGridInfo gridInfo = config.getGridInfo(gid);
            if(gridInfo.getType() == 2){
                buildNum++;
            }
        }
        if(mapDataMap != null){
            for (Map.Entry<Integer, CrossXingYouShanShuiTeamMapData> dataEntry : mapDataMap.entrySet()) {
                CrossXingYouShanShuiTeamMapData value = dataEntry.getValue();
                XingYouShanShuiGridInfo info = config.getGridInfo(value.getGridId());
                if(info.getType() == 2){
                    buildNum--;
                    if(value.getBuildLv() < info.getParam().get(2)){
                        allTopLv = false;
                        break;
                    }
                }
            }
        }
        if(!allTopLv){
            return false;
        }
        if(buildNum == 0){
            return true;
        }
        return false;
    }

    private CrossXingYouShanShuiBuildingLogData getCrossXingYouShanShuiBuildingLogData(CrossXingYouShanShuiUserData userData, int pos, Integer gid, int buildLv) {
        CrossXingYouShanShuiBuildingLogData buildingLogData = new CrossXingYouShanShuiBuildingLogData();
        buildingLogData.setGroupId(this.groupId);
        buildingLogData.setActivityId(config.getActivityInfo().getActivityId());
        buildingLogData.setPlayerId(userData.getUserId());
        buildingLogData.setTeamId(userData.getTeamId());
        buildingLogData.setBuildLv(buildLv + 1);
        buildingLogData.setGridId(gid);
        buildingLogData.setId(maxBuildLogId.incrementAndGet());
        buildingLogData.setMapIndex(pos);
        buildingLogData.setLogTime(System.currentTimeMillis());
        buildingLogData.setInsertOption();
        return buildingLogData;
    }

    /**
     * 招捕快或者随机
     */
    public int yamenRefresh(long serverId, long playerId, int idx) {

        CrossXingYouShanShuiUserData userData = getUserData(playerId);
        if(userData.getTeamId() <= 0){
            return GameErrorCode.E_REQUEST_ARGUMENT_ERROR;
        }
        //容错
        if(userData.isDrift()){
            return GameErrorCode.E_XING_YOU_SHAN_SHUI_ACTION_LIMIT_DRIFT;
        }
        //初始衙门
        CrossXingYouShanShuiTeamData teamData = getTeamData(userData.getTeamId());
        int index = config.getSHANSHUI_MAP().indexOf(14);
        if(index < 0){
            return GameErrorCode.E_GAME_ERROR;
        }
        CrossXingYouShanShuiTeamMapData mapData = getCrossXingYouShanShuiTeamMapData(userData.getTeamId(), index);
        XingYouShanShuiGridInfo gridInfo = config.getGridInfo(eXingYouGridTypes.Fourteen.getId());

        XingYouShanShuiProto.ShanShuiYamenRefreshRsp.Builder clientMsg = XingYouShanShuiProto.ShanShuiYamenRefreshRsp.newBuilder();
        clientMsg.setRet(0);
        synchronized (getTeamLocker(userData.getTeamId())){
            if(userData.getGridParam().isHandled()){
                return GameErrorCode.E_XING_YOU_SHAN_SHUI_GRID_HANDLED;
            }
            if(index != userData.getGridParam().getMapIndex()){
                return GameErrorCode.E_REQUEST_ARGUMENT_ERROR;
            }
            if(idx < 0){
                Integer cost = gridInfo.getParam().get(0);
                if(teamData.getSilverCoin() < cost){
                    return GameErrorCode.E_XING_YOU_SHAN_SHUI_SILVER_NO_ENOUGH;
                }
                //新招募
                if(teamData.getCaptorList().size() >= gridInfo.getParam().get(1)){
                    return GameErrorCode.E_XING_YOU_SHAN_SHUI_CAPTOR_NUM_LIMIT;
                }
                idx = -idx;
                if(teamData.getCaptorList().size() >= idx){
                    syncShanShuiPropNotify(userData.getTeamId(), Arrays.asList(XingYouShanShuiProto.PROP.YA_MEN_POLICE_VALUE));
                    return GameErrorCode.E_XING_YOU_SHAN_SHUI_INFO_OUT_TIME;
                }
                List<Integer> posList = new ArrayList<>(teamData.getCaptorList());
                int newPos = newCaptorPosition(posList, gridInfo);
                if(newPos < 0){
                    return GameErrorCode.E_GAME_ERROR;
                }
                teamData.setSilverCoin(teamData.getSilverCoin() - cost);
                teamData.getCaptorList().add(newPos);
                teamData.setUpdateOption();

                clientMsg.setIndex(newPos);

                Integer gid = config.getSHANSHUI_MAP().get(newPos);


                //招捕快-队伍日志
                CrossXingYouShanShuiTeamActionLogData actionLogData = createActionLogData(userData, XingYouShanShuiProto.ShanShuiLogTypeEnum.SHAN_SHUI_LOG_MARITIME_CUSTOMS_ADMINISTRATION, "",
                        Arrays.asList(String.valueOf(userData.getRoleId()), config.getSHANSHUI_SILVER_COIN_ID() + "=" + cost, String.valueOf(teamData.getCaptorList().size())));
                addCrossXingYouShanShuiTeamActionLogData(actionLogData);

                //日志
                LogCrossXingYouSlive logCrossXingYouSlive = new LogCrossXingYouSlive(teamData.getTeamId(), teamData.getActivityId(), userData.getUserId(), 2, cost, teamData.getSilverCoin(), 2);
                logCrossXingYouSlive.setGroupId(this.groupId);
                CrossAutoLogMgr.add(logCrossXingYouSlive);

                LogCrossXingYouYamen logData = new LogCrossXingYouYamen(userData.getActivityId(), userData.getTeamId(), userData.getUserId(), 1, 0, newPos, gid, 0, 0, 0);
                logData.setGroupId(this.groupId);
                CrossAutoLogMgr.add(logData);
            }else {

                //捕快数量满了，才可以刷新
                if(teamData.getCaptorList().size() != 4){
                    return GameErrorCode.E_REQUEST_ARGUMENT_ERROR;
                }

                if(idx > teamData.getCaptorList().size()){
                    return GameErrorCode.E_REQUEST_ARGUMENT_ERROR;
                }
                //刷新
                Integer id = teamData.getCaptorList().get(idx - 1);
                if(id == null){
                    return GameErrorCode.E_REQUEST_ARGUMENT_ERROR;
                }
                List<Integer> posList = new ArrayList<>(teamData.getCaptorList());
                int newPos = newCaptorPosition(posList, gridInfo);
                if(newPos < 0){
                    return GameErrorCode.E_GAME_ERROR;
                }
                Integer cost = gridInfo.getParam().get(3);
                if(teamData.getSilverCoin() < cost){
                    return GameErrorCode.E_XING_YOU_SHAN_SHUI_SILVER_NO_ENOUGH;
                }
                teamData.setSilverCoin(teamData.getSilverCoin() - cost);

                teamData.getCaptorList().set(idx - 1, newPos);
                teamData.setUpdateOption();

                //日志
                LogCrossXingYouSlive logCrossXingYouSlive = new LogCrossXingYouSlive(teamData.getTeamId(), teamData.getActivityId(), userData.getUserId(), 2, cost, teamData.getSilverCoin(), 2);
                logCrossXingYouSlive.setGroupId(this.groupId);
                CrossAutoLogMgr.add(logCrossXingYouSlive);

                clientMsg.setIndex(newPos);

                Integer gid = config.getSHANSHUI_MAP().get(newPos);

                //刷新捕快位置-队伍日志
                CrossXingYouShanShuiTeamActionLogData actionLogData = createActionLogData(userData, XingYouShanShuiProto.ShanShuiLogTypeEnum.SHAN_SHUI_LOG_MARITIME_CUSTOMS_ADMINISTRATOR_RANDOM, "",
                        Arrays.asList(String.valueOf(userData.getRoleId()), config.getSHANSHUI_SILVER_COIN_ID() + "=" + gridInfo.getParam().get(3)));
                addCrossXingYouShanShuiTeamActionLogData(actionLogData);

                LogCrossXingYouYamen logData = new LogCrossXingYouYamen(userData.getActivityId(), userData.getTeamId(), userData.getUserId(), 2, 0, newPos, gid, 0, 0, 0);
                logData.setGroupId(this.groupId);
                CrossAutoLogMgr.add(logData);
            }
            userData.getGridParam().setHandled(true);
        }
        mapData.setUpdateOption();
        userData.setUpdateOption();

        if(teamData.getCaptorReward() != null) {
            clientMsg.setSilverCoin(teamData.getCaptorReward().getCountByGoodsId(config.getSHANSHUI_SILVER_COIN_ID()).intValue());
        }
        clientMsg.setTeamSilver((int)teamData.getSilverCoin());
        clientMsg.setTeamTotalSilver((int)teamData.getSilverCoinTotal());

        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_XING_YOU_SHAN_SHUI_CATCH_REFRESH, clientMsg));

        syncShanShuiPropNotify(userData.getTeamId(), Collections.singletonList(XingYouShanShuiProto.PROP.TEAM_SILVER_VALUE));

        //通知自己队伍
        syncShanShuiPropNotify(teamData.getTeamId(), Arrays.asList(XingYouShanShuiProto.PROP.YA_MEN_POLICE_VALUE, XingYouShanShuiProto.PROP.TEAM_CUL_SILVER_VALUE, XingYouShanShuiProto.PROP.TEAM_SILVER_VALUE));

        //通知漂泊的玩家
        syncDriftMemberShanShuiPropNotify(teamData.getTeamId(), Collections.singletonList(XingYouShanShuiProto.PROP.YA_MEN_POLICE_VALUE));

        //日志
        return 0;
    }

    /**
     * 衙门奖励领取
     */
    public void yamenReward(long serverId, long playerId) {
        CrossXingYouShanShuiUserData userData = getUserData(playerId);
        if(userData.getTeamId() <= 0){
            return;
        }
        CrossXingYouShanShuiTeamData teamData = getTeamData(userData.getTeamId());
        int index = config.getSHANSHUI_MAP().indexOf(eXingYouGridTypes.Fourteen.getId());
        if(index < 0){
            return;
        }
        XingYouShanShuiProto.ShanShuiYamenRewardRsp.Builder clientMsg = XingYouShanShuiProto.ShanShuiYamenRewardRsp.newBuilder();
        clientMsg.setRet(0);
        if(userData.getGridParam().getId() != eXingYouGridTypes.Fourteen.getId()){
            clientMsg.setRet(GameErrorCode.E_XING_YOU_SHAN_SHUI_GRID_HANDLED);
            MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_XING_YOU_SHAN_SHUI_CATCH_REWARD, clientMsg));
            return;
        }
        CommonTeam team = CommonTeamMgr.getTeam(config.getActivityInfo().getActivityId(), this.groupId, userData.getTeamId());
        synchronized (getTeamLocker(userData.getTeamId())){
            if(teamData.getCaptorReward().isNothing()){
                return;
            }
            Property property = new Property();
            property.addProperty(teamData.getCaptorReward());
            teamData.setCaptorReward(new Property());

            Property reward = new Property();
            if(team != null){
                List<CommonTeamUserData> memberList = new ArrayList<>(team.getMemberDataMap().values());
                int size = memberList.size();
                //平分奖励
                //定时任务 下发奖励
                int sliverCoin = new BigDecimal(property.getCountByGoodsId(config.getSHANSHUI_SILVER_COIN_ID())).divide(BigDecimal.valueOf(size), 0, BigDecimal.ROUND_UP).intValue();
                int goldCoin = new BigDecimal(property.getCountByGoodsId(config.getSHANSHUI_GOLD_COIN_ID())).divide(BigDecimal.valueOf(size), 0, BigDecimal.ROUND_UP).intValue();
                reward.addProperty(config.getSHANSHUI_SILVER_COIN_ID(), sliverCoin);
                reward.addProperty(config.getSHANSHUI_GOLD_COIN_ID(), goldCoin);
                CrossXingYouShanShuiMgr.getThreadPool().addTask(0, new CrossXingYouSendCaptorRewardTask(
                        userData.getUserId(),
                        team.getTeamId(),
                        memberList,
                        reward,
                        this
                ));
            }
            clientMsg.setAward(PropertyHelper.parsePropertyToString(reward));
        }
        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_XING_YOU_SHAN_SHUI_CATCH_REWARD, clientMsg));

//        syncShanShuiPropNotify(userData.getTeamId(), Arrays.asList(XingYouShanShuiProto.PROP.TEAM_SILVER_VALUE, XingYouShanShuiProto.PROP.TEAM_CUL_SILVER_VALUE, XingYouShanShuiProto.PROP.YA_MEN_SILVER_VALUE));
    }

    /**
     * 衙门详情
     */
    public void yamenDetail(long serverId, long playerId) {
        CrossXingYouShanShuiUserData userData = getUserData(playerId);
        if(userData.getTeamId() <= 0){
            return;
        }
        int index = config.getSHANSHUI_MAP().indexOf(14);
        if(index < 0){
            return;
        }
        CrossXingYouShanShuiTeamData teamData = getTeamData(userData.getTeamId());
        XingYouShanShuiProto.ShanShuiYamenDetailRsp.Builder clientMsg = XingYouShanShuiProto.ShanShuiYamenDetailRsp.newBuilder();
        clientMsg.setRet(0);
        if(teamData.getCaptorReward() != null) {
            clientMsg.setSilverCoin(teamData.getCaptorReward().getCountByGoodsId(config.getSHANSHUI_SILVER_COIN_ID()).intValue());
            clientMsg.setGoldCoin(teamData.getCaptorReward().getCountByGoodsId(config.getSHANSHUI_GOLD_COIN_ID()).intValue());
        }
        for (int i = 0; i < teamData.getCaptorList().size(); i++) {
            XingYouShanShuiProto.ShanShuiCaptorInfo.Builder builder = XingYouShanShuiProto.ShanShuiCaptorInfo.newBuilder();
            builder.setId(i + 1);
            builder.setIndex(teamData.getCaptorList().get(i));
            clientMsg.addCaptor(builder);
        }
        List<CrossXingYouShanShuiCatchLogData> logDataList = teamCatchDataMap.get(userData.getTeamId());
        if(logDataList != null) {
            for (int i = 0; i < logDataList.size(); i++) {
                CrossXingYouShanShuiCatchLogData logData = logDataList.get(i);
                XingYouShanShuiProto.ShanShuiYamenCatchLog.Builder builder = XingYouShanShuiProto.ShanShuiYamenCatchLog.newBuilder();
                builder.setPlayerId(logData.getTargetUserId());
                builder.setSilverCoin(0);
                builder.setReward(logData.getSeizeCount());
                builder.setTime(logData.getCatchTime());
                builder.setNickName(logData.getNickName());
                CrossXingYouShanShuiUserData target = getUserData(logData.getTargetUserId());
                CommonTeam team = CommonTeamMgr.getTeam(config.getActivityInfo().getActivityId(), this.groupId, target.getTeamId());
                if (team != null) {
                    builder.setTeamName(team.getTeamName());
                }
                clientMsg.addLog(builder);
            }
        }
        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_XING_YOU_SHAN_SHUI_CATCH_DETAIL, clientMsg));
    }

    /**
     * 刷新捕快位置
     * @param posList 现有位置
     * @param gridInfo
     */
    private int newCaptorPosition(List<Integer> posList, XingYouShanShuiGridInfo gridInfo) {
        List<Integer> limitList= new ArrayList<>();
        int size = config.getSHANSHUI_MAP().size();
        int gap = gridInfo.getParam().get(2);
        for (int pos : posList) {
            for (int i = 1; i <= gap; i++) {
                int newPos = pos + i;
                if(newPos > size - 1){
                    newPos = newPos % size;
                }
                limitList.add(newPos);
            }
            for (int i = 1; i <= gap; i++) {
                int newPos = pos - i;
                if(newPos < 0){
                    newPos = size + newPos;
                }
                limitList.add(newPos);
            }
        }
        limitList.addAll(posList);
        List<Integer> resultList = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            if(i == 0 || limitList.contains(i)){
                continue;
            }
            int gridId = config.getSHANSHUI_MAP().get(i);
            //排除 挑战格、妈祖、玉门关
            if(gridId == eXingYouGridTypes.Fifteen.getId() || gridId == eXingYouGridTypes.Seventeen.getId() || gridId == eXingYouGridTypes.Sixteen.getId()){
                continue;
            }
            resultList.add(i);
        }
        if(resultList.isEmpty()){
            return -1;
        }
        int index = new Random().nextInt(resultList.size());
        return resultList.get(index);
    }

    /**
     * 祈愿信息
     */
    public void wishInfo(long serverId, long playerId) {
        CrossXingYouShanShuiUserData userData = getUserData(playerId);
        if(userData.getTeamId() <= 0){
            return;
        }
        CrossXingYouShanShuiTeamData teamData = getTeamData(userData.getTeamId());
        XingYouShanShuiProto.ShanShuiTradeShipInfoRsp.Builder clientMsg = XingYouShanShuiProto.ShanShuiTradeShipInfoRsp.newBuilder();
        clientMsg.setRet(0);
        XingYouShanShuiProto.ShanShuiTradeShipInfo.Builder builder = XingYouShanShuiProto.ShanShuiTradeShipInfo.newBuilder();
        builder.setProgress(teamData.getWishValue());
        builder.setRound(teamData.getWishRound());
        builder.setAddedProgress(0);
        if(userData.getGridParam().getId() == eXingYouGridTypes.Thirteen.getId()){
            builder.setAddedProgress(userData.getGridParam().getBuy());
        }
        clientMsg.setTradeShipInfo(builder);
        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_XING_YOU_SHAN_SHUI_TRADE_SHIP_REWARD_PROGRESS, clientMsg));
    }

    /**
     * 祈愿轮次奖励列表
     */
    public void wishRewardRecord(long serverId, long playerId) {
        CrossXingYouShanShuiUserData userData = getUserData(playerId);
        if(userData.getTeamId() <= 0){
            return;
        }
        XingYouShanShuiProto.ShanShuiTradeShipRewardRecordRsp.Builder clientMsg = XingYouShanShuiProto.ShanShuiTradeShipRewardRecordRsp.newBuilder();
        clientMsg.setRet(0);
        CrossXingYouShanShuiTeamData teamData = getTeamData(userData.getTeamId());

        List<CrossXingYouShanShuiWishRewardData> dataList = teamWishRewardMap.get(userData.getTeamId());
        if(dataList != null){
            for (int i = 0; i < dataList.size(); i++) {

                XingYouShanShuiProto.ShanShuiTradeShipRewardRecordInfo.Builder  recordBuilder = XingYouShanShuiProto.ShanShuiTradeShipRewardRecordInfo.newBuilder();

                CrossXingYouShanShuiWishRewardData rewardData = dataList.get(i);
                recordBuilder.setRound(rewardData.getRound());

                for (Map.Entry<Long, ShanShuiUserWishReward> entry : rewardData.getRewardMap().entrySet()) {
                    long uid = entry.getKey();
                    XingYouShanShuiProto.ShanShuiTradeShipRewardInfo.Builder builder = XingYouShanShuiProto.ShanShuiTradeShipRewardInfo.newBuilder();
                    builder.setPlayerId(uid);
                    ShanShuiUserWishReward value = entry.getValue();
                    builder.setReward(value.getReward());
                    builder.setIndexId(value.getIndex());
                    builder.setIsSpecial(value.getBig() == 1);
                    recordBuilder.addRewardInfoList(builder);
                }

                clientMsg.addRecordInfoList(recordBuilder);

            }
        }

        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_XING_YOU_SHAN_SHUI_TRADE_SHIP_REWARD_RECORD, clientMsg));
    }

    /**
     * 领取祈愿分享奖励
     */
    public void getWishGift(long serverId, long playerId) {
        CrossXingYouShanShuiUserData userData = getUserData(playerId);
        if(userData.getTeamId() <= 0){
            return;
        }
        XingYouShanShuiProto.ShanShuiTradeShipGiftRsp.Builder clientMsg = XingYouShanShuiProto.ShanShuiTradeShipGiftRsp.newBuilder();
        clientMsg.setRet(0);
        //修改个人祈愿数据的也用队伍锁，骰子那边玩家锁里面不能套玩家锁，所以统一有操作其他队友的祈愿数据都套队伍锁
        synchronized (getTeamLocker(userData.getTeamId())){
            if(userData.getWishShareValue() <= 0){
                clientMsg.setRet(1);
                clientMsg.setWishShareLastGetTime(userData.getWishShareLastGetTime());
                MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_XING_YOU_SHAN_SHUI_TRADE_SHIP_GIFT, clientMsg));
                return;
            }
            clientMsg.setAward(config.getSHANSHUI_GOLD_COIN_ID() + "=" + userData.getWishShareValue());
            userData.setWishShareValue(0);
            userData.setWishShareLastGetTime(System.currentTimeMillis());
        }
        clientMsg.setWishShareLastGetTime(userData.getWishShareLastGetTime());
        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.S_XING_YOU_SHAN_SHUI_TRADE_SHIP_GIFT_FROM_CROSS, clientMsg));
    }

    /**
     * 获取建筑信息
     */
    public XingYouShanShuiProto.ShanShuiBuildingDetailRsp.Builder buildingInfoMsg(long playerId, long teamId, int position) {
        XingYouShanShuiProto.ShanShuiBuildingDetailRsp.Builder clientMsg = XingYouShanShuiProto.ShanShuiBuildingDetailRsp.newBuilder();
        clientMsg.setRet(0);
        CrossXingYouShanShuiUserData userData = getUserData(playerId);
        int userDataTeamId = userData.getTeamId();
        if(userData.isDrift()){
            userDataTeamId = userData.getMapTeamId();
        }
        if(userDataTeamId <= 0){
            clientMsg.setRet(GameErrorCode.E_COMMON_TEAM_TEAM_USER_NOT_EXIST);
            return clientMsg;
        }
        Integer gid = config.getSHANSHUI_MAP().get(position);
        XingYouShanShuiGridInfo paramGrid = config.getGridInfo(gid);
        if(paramGrid.getType() != 2){
            clientMsg.setRet(GameErrorCode.E_REQUEST_ARGUMENT_ERROR);
            return clientMsg;
        }
        CrossXingYouShanShuiTeamMapData teamMapData = getCrossXingYouShanShuiTeamMapDataIfNull(userDataTeamId, position);
        if(teamMapData == null){
            clientMsg.setBuildingId(gid);
            clientMsg.setBuildingLevel(0);
            clientMsg.setBuildingState(0);
            clientMsg.setRet(0);
            return clientMsg;
        }
        XingYouShanShuiGridInfo gridInfo = config.getGridInfo(teamMapData.getGridId());
        if(gridInfo == null || gridInfo.getType() != 2){
            clientMsg.setRet(GameErrorCode.E_REQUEST_ARGUMENT_ERROR);
            return clientMsg;
        }
        clientMsg.setBuildingId(teamMapData.getGridId());
        clientMsg.setBuildingLevel(teamMapData.getBuildLv());
        List<CrossXingYouShanShuiBuildingLogData> dataList = buildLogMap.get(userDataTeamId);
        if(dataList != null){
            for (int i = 0; i < dataList.size(); i++) {
                CrossXingYouShanShuiBuildingLogData logData = dataList.get(i);
                if(logData.getGridId() != gid){
                    continue;
                }
                XingYouShanShuiProto.ShanShuiBuildingLog.Builder builder = XingYouShanShuiProto.ShanShuiBuildingLog.newBuilder();
                builder.setPlayerId(logData.getPlayerId());
                builder.setBuildingLevel(logData.getBuildLv());
                builder.setIsUseItem(logData.getIsUseItem() == 1);
                builder.setTime(logData.getLogTime());
                clientMsg.addBuildingLog(builder);
            }
        }
        clientMsg.setBuildingState(teamMapData.getCloseTimes());
        return clientMsg;
    }

    /**
     * 队伍榜单变更
     */
    public void changeTeamRank(int teamId) {
        CrossXingYouShanShuiTeamData teamData = getTeamData(teamId);
        int activityId = this.getConfig().getActivityInfo().getActivityId();
        //获取队伍的山海灵气
        long auraScore = teamData.getSilverCoinTotal();
        //队伍榜单变更
        CommonTeamMgr.changeTeamRankScore(activityId, this.groupId, eGamePlayerEventType.XingYouShanShuiTeamSliverRank.getValue(), teamId, auraScore, 0);
    }

    /**
     * 队伍总体力消耗
     */
    public int getTeamTotalUseEnergy(int teamId){
        int total = 0;
        CommonTeamActivity activity = CommonTeamMgr.getActivity(config.getActivityInfo().getActivityId(), this.groupId);
        if(activity != null){
            CommonTeam team = activity.getTeam(teamId);
            if(team != null){
                for (Map.Entry<Long, CommonTeamUserData> entry : team.getMemberDataMap().entrySet()) {
                    CrossXingYouShanShuiUserData userData = getUserData(entry.getKey());
                    total += userData.getUseEnergy();
                }
            }
        }
        return total;
    }

    /**
     * 领取祈愿轮次奖励
     */
    public int wishGetReward(long serverId, long playerId, int round, int indexId) {
        CrossXingYouShanShuiUserData userData = getUserData(playerId);
        if(userData.getTeamId() <= 0){
            return GameErrorCode.E_XING_YOU_SHAN_SHUI_PLAYER_NO_TEAM;
        }
        CrossXingYouShanShuiWishRewardData rewardData = null;

        List<CrossXingYouShanShuiWishRewardData> dataList = teamWishRewardMap.get(userData.getTeamId());
        if(dataList != null) {
            for (int i = 0; i < dataList.size(); i++) {
                CrossXingYouShanShuiWishRewardData data = dataList.get(i);
                if (data.getRound() == round) {
                    rewardData = data;
                    break;
                }
            }
        }
        if(rewardData == null){
            //轮次错误
            return GameErrorCode.E_REQUEST_ARGUMENT_ERROR;
        }
        XingYouShanShuiGridInfo gridInfo = config.getGridInfo(eXingYouGridTypes.Thirteen.getId());
        ShanShuiUserWishReward reward;
        synchronized (getTeamData(userData.getTeamId())){
            if(rewardData.getRewardMap().containsKey(playerId)){
                //已经领取
                return GameErrorCode.E_XING_YOU_SHAN_SHUI_TEAM_REWARD_GOT;
            }
            //是否开过大奖
            boolean canBig = true;
            int big = 0;
            int gotNum = rewardData.getRewardMap().size();
            for (Map.Entry<Long, ShanShuiUserWishReward> entry : rewardData.getRewardMap().entrySet()) {
                ShanShuiUserWishReward value = entry.getValue();
                if(value.getIndex() == indexId){
                    //已经被选择
                    return GameErrorCode.E_XING_YOU_SHAN_SHUI_INFO_OUT_TIME;
                }
                if(value.getBig() == 1){
                    canBig = false;
                }
            }

            if(canBig){
                //走概率
                int num = 100 / (4 - gotNum);
                if(new Random().nextInt(100) < num){
                    big = 1;
                }
            }

            Property property;
            if(big == 1){
                //大奖励
                //区服小大佛
                List<String> stringList = StringUtils.stringToStringList(gridInfo.getReward1(), "\\|");
                String poolReard = stringList.get(0);
                if(rewardData.getRound() > gridInfo.getParam().get(8)){
                    poolReard = stringList.get(1);
                }
                property = RandomWeightConfigHelper.getProperty(poolReard);

                //大奖励
                CrossXingYouShanShuiTeamActionLogData logData = createActionLogData(userData, XingYouShanShuiProto.ShanShuiLogTypeEnum.SHAN_SHUI_LOG_TRADE_SHIP_RECEIVE, PropertyHelper.parsePropertyToString(property),
                        String.valueOf(userData.getRoleId()));
                addCrossXingYouShanShuiTeamActionLogData(logData);

            }else {
                //小奖励
                List<String> stringList = StringUtils.stringToStringList(gridInfo.getReward2(), "\\|");
                String poolReard = stringList.get(0);
                if(rewardData.getRound() > gridInfo.getParam().get(8)){
                    poolReard = stringList.get(1);
                }
                property = RandomWeightConfigHelper.getProperty(poolReard);
            }

            LogCrossXingYouWishRoundReward logData = new LogCrossXingYouWishRoundReward(userData.getActivityId(), userData.getTeamId(), userData.getUserId(), round, PropertyHelper.parsePropertyToString(property), big);
            logData.setGroupId(this.groupId);
            CrossAutoLogMgr.add(logData);

            reward = new ShanShuiUserWishReward();
            reward.setBig(big);
            reward.setIndex(indexId);
            reward.setReward(PropertyHelper.parsePropertyToString(property));
            reward.setUserId(playerId);
            rewardData.getRewardMap().put(playerId, reward);
            rewardData.setUpdateOption();

            addWishDataUpdate(rewardData);
        }

        XingYouShanShuiProto.ShanShuiTradeShipRewardReceiveRsp.Builder respMsg = XingYouShanShuiProto.ShanShuiTradeShipRewardReceiveRsp.newBuilder();
        respMsg.setRet(0);
        respMsg.setAward(reward.getReward());
        respMsg.setIsSpecial(reward.getBig() == 1);

        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.S_XING_YOU_SHAN_SHUI_TRADE_SHIP_REWARD_RECEIVE_FROM_CROSS, respMsg));
        needSyncRedDotUserMap.add(userData.getUserId());
        return 0;

    }

    /**
     * 随机一个挑战的玩家
     */
    public long randomTzEmeny(int teamId){
        CrossXingYouShanShuiTeamData teamData = getTeamData(teamId);
        //先随机非商会的5个队伍
        List<Integer> randomTemList = getRandomTemList(teamData, 10, Collections.emptyList());
        CommonTeamActivity activity = CommonTeamMgr.getActivity(config.getActivityInfo().getActivityId(), this.groupId);
        if(activity == null){
            return 0;
        }
        List<Long> userIdList = new ArrayList<>();
        Map<Integer, CrossXingYouShanShuiTeamMapData> mapDataMap = getCrossXingYouShanShuiTeamMapData(teamId);
        if(mapDataMap != null){
            for (Map.Entry<Integer, CrossXingYouShanShuiTeamMapData> entry : mapDataMap.entrySet()) {
                CrossXingYouShanShuiTeamMapData value = entry.getValue();
                if(value.getTzUserId() > 0){
                    userIdList.add(value.getTzUserId());
                }
            }
        }
        List<Long> poolList = new ArrayList<>();
        for (Integer tid : randomTemList) {
            CommonTeam team = activity.getTeam(tid);
            if(team != null){
                for (Map.Entry<Long, CommonTeamUserData> entry : team.getMemberDataMap().entrySet()) {
                    long uid = entry.getKey();
                    if(userIdList.contains(uid)){
                        continue;
                    }
                    poolList.add(uid);
                }
            }
        }
        if(poolList.isEmpty()){
            return 0;
        }
        int i = new Random().nextInt(poolList.size());
        return poolList.get(i);
    }

    public XingYouShanShuiProto.ShanShuiBattleRecordMsg.Builder battle(long userId, long targetId, List<ShanShuiBeauty> targetBeautyList, int targetHp){
        if(targetId > 0){
            CrossXingYouShanShuiUserData targetUserData = getUserData(targetId);
            targetBeautyList = targetUserData.getBeautyList();
        }

        CrossXingYouShanShuiUserData userData = getUserData(userId);
        List<ShanShuiBeauty> beautyList = new ArrayList<>(userData.getBeautyList());
        List<ShanShuiBeauty> enemyBeautyList = new ArrayList<>(targetBeautyList);
        int hp = 0;
        for (ShanShuiBeauty beauty : beautyList) {
            hp += beauty.getTotal();
        }
        Map<Integer, Integer> beautyTimesMap = new HashMap<>();
        Map<Integer, Integer> enemyBeautyTimesMap = new HashMap<>();

        XingYouShanShuiProto.ShanShuiBattleMainMsg.Builder myBuilder = XingYouShanShuiProto.ShanShuiBattleMainMsg.newBuilder();
        myBuilder.setPlayerId(userId);
        myBuilder.setMaxHp(hp);
        myBuilder.setTotalPower(hp);
        UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(userId);
        if(userBaseInfo != null) {
            myBuilder.setUserBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
        }

        int targetTotal = 0;
        for (ShanShuiBeauty beauty : enemyBeautyList) {
            targetTotal += beauty.getTotal();
        }

        if(targetHp == 0){
            targetHp = targetTotal;
        }

        XingYouShanShuiProto.ShanShuiBattleMainMsg.Builder enemyBuilder = XingYouShanShuiProto.ShanShuiBattleMainMsg.newBuilder();
        enemyBuilder.setPlayerId(targetId);
        enemyBuilder.setMaxHp(targetTotal);
        enemyBuilder.setTotalPower(targetTotal);
        if(targetId > 0) {
            UserBaseInfo enmeyUserBaseInfo = CrossUserMgr.getUserBaseInfo(targetId);
            if (enmeyUserBaseInfo != null) {
                enemyBuilder.setUserBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(enmeyUserBaseInfo));
            }
        }

        //初始血量
        myBuilder.setHp(hp);
        enemyBuilder.setHp(targetHp);


        for (ShanShuiBeauty beauty : beautyList) {
            XingYouShanShuiProto.ShanShuiBeautyInfoMsg.Builder builder = XingYouShanShuiProto.ShanShuiBeautyInfoMsg.newBuilder();
            builder.setBeautyId(beauty.getId());
            builder.setSkinId(beauty.getIc());
            builder.setMacy(beauty.getMacy());
            builder.setMour(beauty.getMour());
            myBuilder.addBeautyInfos(builder);
        }

        for (ShanShuiBeauty beauty : enemyBeautyList) {
            XingYouShanShuiProto.ShanShuiBeautyInfoMsg.Builder builder = XingYouShanShuiProto.ShanShuiBeautyInfoMsg.newBuilder();
            builder.setBeautyId(beauty.getId());
            builder.setSkinId(beauty.getIc());
            builder.setMacy(beauty.getMacy());
            builder.setMour(beauty.getMour());
            enemyBuilder.addBeautyInfos(builder);
        }

        Random random = new Random();
        XingYouShanShuiProto.ShanShuiBattleRecordMsg.Builder builder = XingYouShanShuiProto.ShanShuiBattleRecordMsg.newBuilder();
        boolean win = false;
        int round = 0;
        if(enemyBeautyList.isEmpty()){
            win = true;
        }else {
            while (hp > 0 && targetHp > 0 && beautyList.size() > 0 && enemyBeautyList.size() > 0){
                List<Integer> weightList = new ArrayList<>();
                for (ShanShuiBeauty beauty : beautyList) {
                    weightList.add(beauty.getTotal());
                }
                int index = RandomHelper.getRandomIndexByWeight(weightList, random);
                ShanShuiBeauty my = beautyList.get(index);

                weightList = new ArrayList<>();
                for (ShanShuiBeauty beauty : enemyBeautyList) {
                    weightList.add(beauty.getTotal());
                }
                index = RandomHelper.getRandomIndexByWeight(weightList, random);
                ShanShuiBeauty enemy = enemyBeautyList.get(index);

                XingYouShanShuiProto.ShanShuiBattleRoundMsg.Builder roundBuilder = XingYouShanShuiProto.ShanShuiBattleRoundMsg.newBuilder();
                roundBuilder.setRound(++round);
                roundBuilder.setAtkPlayerId(userId);
                roundBuilder.setAtkBeautyId(my.getId());
                roundBuilder.setHurt(Math.min(targetHp, my.getTotal()));
                builder.addRounds(roundBuilder);

                targetHp -= roundBuilder.getHurt();

                if(targetHp <= 0){
                    win = true;
                    builder.addPlayers(myBuilder);
                    builder.addPlayers(enemyBuilder);
                    break;
                }

                XingYouShanShuiProto.ShanShuiBattleRoundMsg.Builder roundBuilder2 = XingYouShanShuiProto.ShanShuiBattleRoundMsg.newBuilder();
                roundBuilder2.setRound(++round);
                roundBuilder2.setAtkPlayerId(targetId);
                roundBuilder2.setAtkBeautyId(enemy.getId());
                roundBuilder2.setHurt(Math.min(hp, enemy.getTotal()));
                builder.addRounds(roundBuilder2);

                hp -= roundBuilder2.getHurt();
                if(hp <= 0){
                    builder.addPlayers(myBuilder);
                    builder.addPlayers(enemyBuilder);
                    break;
                }
                int times = beautyTimesMap.getOrDefault(my.getId(), 0);
                beautyTimesMap.put(my.getId(), times + 1);
                int enemyTimes = enemyBeautyTimesMap.getOrDefault(enemy.getId(), 0);
                enemyBeautyTimesMap.put(enemy.getId(), enemyTimes + 1);
                if(beautyTimesMap.get(my.getId()) >= config.getBEAUTY_ATTACK_NUM()){
                    beautyList.remove(my);
                }
                if(enemyBeautyTimesMap.get(enemy.getId()) >= config.getBEAUTY_ATTACK_NUM()){
                    enemyBeautyList.remove(enemy);
                }
                if(beautyList.isEmpty()){
                    builder.addPlayers(myBuilder);
                    builder.addPlayers(enemyBuilder);
                    break;
                }
                if(enemyBeautyList.isEmpty()){
                    win = true;
                    builder.addPlayers(myBuilder);
                    builder.addPlayers(enemyBuilder);
                    break;
                }
            }
        }
        if(builder.getPlayersCount() == 0){
            builder.addPlayers(myBuilder);
            builder.addPlayers(enemyBuilder);
        }
        builder.setEnemyHp(targetHp);

        builder.setIsWin(win);
        return builder;
    }

    /**
     * 妈祖庙详情
     */
    public void maZuDetail(long serverId, long playerId) {
        CrossXingYouShanShuiUserData userData = getUserData(playerId);


        XingYouShanShuiProto.ShanShuiTowerDetailRsp.Builder clientMsg = XingYouShanShuiProto.ShanShuiTowerDetailRsp.newBuilder();
        clientMsg.setRet(0);
        clientMsg.setMyDeclare(userData.getDeclaration());


        XingYouShanShuiProto.ShanShuiTowerDetail.Builder builder = getMaZuBuilder();

        clientMsg.setRet(0);
        clientMsg.setTowerDetail(builder);

        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_XING_YOU_SHAN_SHUI_TOWER_DETAIL, clientMsg));

    }

    /**
     * 购买角色
     */
    public void buyRole(long serverId, long playerId, int roleId, String consume) {
        CrossXingYouShanShuiUserData userData = getUserData(playerId);
        if(userData.getTeamId() <= 0){
            return;
        }
        XingYouShanShuiProto.CrossShanShuiBuyRoleChessRsp.Builder chessRsp = XingYouShanShuiProto.CrossShanShuiBuyRoleChessRsp.newBuilder();
        chessRsp.setConsume(consume);
        XingYouShanShuiProto.ShanShuiBuyRoleChessRsp.Builder builder = XingYouShanShuiProto.ShanShuiBuyRoleChessRsp.newBuilder();
        builder.setRet(0);
        CommonTeam team = CommonTeamMgr.getTeam(config.getActivityInfo().getActivityId(), this.groupId, userData.getTeamId());
        if(team == null){
            return;
        }
        synchronized (getTeamLocker(userData.getTeamId())){
            if(team.getLeaderId() != playerId){
                builder.setRet(GameErrorCode.E_XING_YOU_SHAN_SHUI_TEAM_LEADER_LIMIT);
            }else {
                if(userData.getBuyRole().contains(roleId)){
                    //已购买
                    builder.setRet(GameErrorCode.E_XING_YOU_SHAN_SHUI_INFO_OUT_TIME);
                }else {
                    userData.getBuyRole().add(roleId);
                    userData.setUpdateOption();
                }
            }
        }
        builder.addAllBuyRoleId(userData.getBuyRole());
        chessRsp.setRsp(builder);
        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.S_XING_YOU_SHAN_SHUI_BUY_ROLE_FROM_CROSS, chessRsp));
    }

    private XingYouShanShuiProto.ShanShuiTowerDetail.Builder getMaZuBuilder() {
        XingYouShanShuiProto.ShanShuiTowerDetail.Builder builder = XingYouShanShuiProto.ShanShuiTowerDetail.newBuilder();
        builder.setDeclare("");

        long userId = shanShuiData.getUserId();
        long hp = shanShuiData.getHp();
        long totalHp = shanShuiData.getTotalHp();

        if(userId > 0){
            CrossXingYouShanShuiUserData boss = getUserData(userId);
            CrossXingYouShanShuiTeamData bossTeam = getTeamData(boss.getTeamId());
            builder.setTeamId(bossTeam.getTeamId());
            builder.setPlayerId(boss.getUserId());
            CommonTeam team = CommonTeamMgr.getTeam(config.getActivityInfo().getActivityId(), this.groupId, boss.getTeamId());
            if(team != null) {
                builder.setTeamName(team.getTeamName());
            }
            UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(userId);
            if(userBaseInfo != null){
                builder.setNickName(userBaseInfo.getNickName());
                builder.setAppearanceId(userBaseInfo.getDecoration());
            }
            builder.setDeclare(boss.getDeclaration());
        }else {
            builder.setTeamId(0);
            builder.setPlayerId(0);
            builder.setNickName("");
            builder.setTeamName("");
        }
        builder.setFightValue(totalHp);
        builder.setHpMax(totalHp);
        builder.setHpPercent(hp);
        builder.setProtectEndT(shanShuiData.getMaZuChangeTime() + config.getSHUISHUI_MAZU_PROTECT_TIME());
        return builder;
    }

    /**
     * 妈祖庙设置宣言
     */
    public void maZuSetDeclare(long serverId, long playerId, String declare) {
        CrossXingYouShanShuiUserData userData = getUserData(playerId);
        CrossXingYouShanShuiTeamData teamData = getTeamData(userData.getTeamId());
        synchronized (getUserLocker(userData.getUserId())){
            int currentSecond = DateHelper.getCurrentSecond();
            if(inMazuTemp(userData) && userData.getDeclareCd() > 0 && userData.getDeclareCd() + config.getSHANSHUI_ANNOUNCE_RESET_TIME() > currentSecond){
                XingYouShanShuiProto.ShanShuiTowerDeclareRsp.Builder clientMsg = XingYouShanShuiProto.ShanShuiTowerDeclareRsp.newBuilder();
                clientMsg.setRet(GameErrorCode.E_XING_YOU_SHAN_SHUI_DECLARATION_CD);
                MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_XING_YOU_SHAN_SHUI_TOWER_DECLARE, clientMsg));
                return;
            }
            teamData.setDeclaration(declare);
            userData.setDeclaration(declare);
            userData.setDeclareCd(currentSecond);
        }
        boolean changed = false;
        synchronized (lock){
            if(shanShuiData.getUserId() > 0){
                CrossXingYouShanShuiUserData boss = getUserData(shanShuiData.getUserId());
                if(boss.getTeamId() == userData.getTeamId()){
                    changed = true;
                }
            }
        }
        XingYouShanShuiProto.ShanShuiTowerDeclareRsp.Builder clientMsg = XingYouShanShuiProto.ShanShuiTowerDeclareRsp.newBuilder();
        clientMsg.setRet(0);
        clientMsg.setLastDeclareTime(userData.getDeclareCd());
        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_XING_YOU_SHAN_SHUI_TOWER_DECLARE, clientMsg));
        if(changed){
            shanShuiData.isNeedSync().getAndSet(true);
        }
    }

    /**
     * 放弃事件
     */
    public void giveUpEvent(long serverId, long playerId) {

        CrossXingYouShanShuiUserData userData = getUserData(playerId);
        if(userData.isDrift()){
            userData.getDriftGridParam().setHandled(true);
        }else {
            userData.getGridParam().setHandled(true);
        }
        userData.setUpdateOption();

        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_XING_YOU_SHAN_SHUI_GIVE_UP_EVENT, XingYouShanShuiProto.ShanShuiGiveUpEventRsp.newBuilder().setRet(0)));

    }

    /**
     * 玩家离开
     */
    public void leave(long serverId, long playerId) {
        inMapUserSet.remove(playerId);
    }

    /**
     * 获得建筑的奖励
     */
    public Property getBuildingReward(XingYouShanShuiGridInfo gridInfo, XingYouConfig config, int buildingLv, int closeTimes, boolean isDrift, boolean stop){
        Property property = new Property();
        if(buildingLv > 0){
            //已修葺，有奖励
            int count = gridInfo.getParam().get(3) + (buildingLv - 1) * gridInfo.getParam().get(4);
            //银票
            if(gridInfo.getId() == eXingYouGridTypes.Ten.getId()){
                property.addProperty(config.getSHANSHUI_GOLD_COIN_ID(), count);
            }else {
                property.addProperty(config.getSHANSHUI_SILVER_COIN_ID(), count);
            }
            if(!isDrift){
                //受闭园状态影响
                XingYouShanShuiGridInfo yumenGrid = config.getGridInfo(eXingYouGridTypes.Sixteen.getId());
                if(yumenGrid != null && closeTimes > 0){
                    BigDecimal divide = BigDecimal.valueOf(1000 - yumenGrid.getParam().get(2)).divide(BigDecimal.valueOf(1000), 3, BigDecimal.ROUND_UP);
                    property.rideProperty(divide);
                }
            }else {
                //漂泊状态，特定加成？
                if(stop){
                    XingYouShanShuiGridInfo yumenGrid = config.getGridInfo(eXingYouGridTypes.Sixteen.getId());
                    if(yumenGrid != null){
                        BigDecimal divide = BigDecimal.valueOf(1000 + yumenGrid.getParam().get(1)).divide(BigDecimal.valueOf(1000), 3, BigDecimal.ROUND_UP);
                        property.rideProperty(divide);
                    }
                }
            }
            //满级
//            if(buildingLv >= gridInfo.getParam().get(2) && stop){
            if(stop){ //需求改为停留才有奖励
                property.addProperty(PropertyHelper.parseStringToProperty(gridInfo.getReward1()));
            }
        }
        return property;
    }

    public String getRoleName(CrossXingYouShanShuiUserData userData, String language){
        XingYouShanShuiRoleInfo info = null;
        for (XingYouShanShuiRoleInfo roleInfo : config.getRoleInfoList()) {
            if(userData.getRoleId() == roleInfo.getId()){
                info = roleInfo;
            }
        }
        if(info != null){
            return ServerLanguageMgr.getContent(info.getName(), language);
        }
        return "";
    }

    public int getRoleBuffAddition(CrossXingYouShanShuiUserData userData, int roleId){
        if(userData.getRoleId() != roleId){
            return 0;
        }
        XingYouShanShuiRoleInfo roleInfo = config.getRoleInfo(roleId);
        if(roleInfo == null){
            return 0;
        }
        return roleInfo.getSkillParam().get(0);
    }

    public CrossXingYouShanShuiTeamData getTeamDataIfNull(int teamId){
        return teamDataMap.get(teamId);
    }

    public CrossXingYouShanShuiTeamMapData getCrossXingYouShanShuiTeamMapDataIfNull(int teamId, int index){
        Map<Integer, CrossXingYouShanShuiTeamMapData> dataMap = teamMapDataMap.get(teamId);
        if(dataMap == null){
            return null;
        }
        return dataMap.get(index);
    }

    public Map<Integer, CrossXingYouShanShuiTeamMapData> getCrossXingYouShanShuiTeamMapData(int teamId){
        return teamMapDataMap.get(teamId);
    }

    public CrossXingYouShanShuiTeamMapData getCrossXingYouShanShuiTeamMapData(int teamId, int index){
        Map<Integer, CrossXingYouShanShuiTeamMapData> dataMap = teamMapDataMap.get(teamId);
        if(dataMap == null){
            synchronized (teamMapDataMap){
                dataMap = teamMapDataMap.get(teamId);
                if(dataMap == null){
                    dataMap = new ConcurrentHashMap<>();
                    teamMapDataMap.put(teamId, dataMap);
                }
            }
        }
        CrossXingYouShanShuiTeamMapData data = dataMap.get(index);
        if(data == null){
            synchronized (dataMap){
                data = dataMap.get(index);
                if(data == null){
                    data =  new CrossXingYouShanShuiTeamMapData();
                    data.setGroupId(this.groupId);
                    data.setActivityId(config.getActivityInfo().getActivityId());
                    data.setMapIndex(index);
                    data.setTeamId(teamId);
                    Integer gid = config.getSHANSHUI_MAP().get(index);
                    data.setGridId(gid);
                    data.setInsertOption();
                    dataMap.put(index, data);
                }
            }
        }
        return data;
    }

    public CrossXingYouShanShuiTeamData getTeamData(int teamId){
        if(teamId == 0){
            return null;
        }
        CrossXingYouShanShuiTeamData teamData = teamDataMap.get(teamId);
        CommonTeamActivity activity = CommonTeamMgr.getActivity(config.getActivityInfo().getActivityId(), this.groupId);
        if(teamData == null){
            synchronized (teamDataMap){
                teamData = teamDataMap.get(teamId);
                if(teamData == null){
                    teamData = new CrossXingYouShanShuiTeamData();
                    teamData.setGroupId(this.groupId);
                    teamData.setInsertOption();
                    teamData.setActivityId(config.getActivityInfo().getActivityId());
                    teamData.setTeamId(teamId);
                    teamData.setWishRound(1);
                    if(activity != null){
                        CommonTeam team = activity.getTeam(teamId);
                        if(team != null) {
                            teamData.setMasterId(team.getLeaderId());
                        }
                    }
                    teamData.setTodayTeam(new ArrayList<>());
                    teamData.setRandomTodayTeam(new ArrayList<>());
                    teamData.setVisitorMap(new ConcurrentHashMap<>());
                    teamData.setCaptorReward(new Property());
                    teamData.setCaptorList(new ArrayList<>());
                    teamDataMap.put(teamId, teamData);
                }
            }
        }
        if(teamData.getMasterId() == 0){
            if(activity != null){
                CommonTeam team = activity.getTeam(teamId);
                if(team != null){
                    teamData.setMasterId(team.getLeaderId());
                }
            }
        }
        return teamData;
    }

    public CrossXingYouShanShuiUserData getUserData(long userId){
        CrossXingYouShanShuiUserData userData = userDataMap.get(userId);
        if(userData == null){
            synchronized (userDataMap){
                userData = userDataMap.get(userId);
                if(userData == null){
                    userData = new CrossXingYouShanShuiUserData();
                    userData.setGroupId(this.groupId);
                    userData.setInsertOption();
                    userData.setActivityId(config.getActivityInfo().getActivityId());
                    userData.setUserId(userId);
                    userData.setEnergy(config.getSHANSHUI_DICE_INITIAL_NUM());
                    userData.setEnergyLastTime(System.currentTimeMillis() / 1000);
                    userData.setBuyRole(new ArrayList<>());
                    userData.setHelpTimes(config.getSHANSHUI_HELP_TIME());
                    Integer gid = config.getSHANSHUI_MAP().get(0);
                    userData.setDriftReward(new Property());
                    userData.setCaptorReward(new Property());
                    ShanShuiGridParam gridParam = new ShanShuiGridParam(gid, 0, true, false);
                    userData.setGridParam(gridParam);
                    int start = config.getSHANSHUI_OTHER_MAP().indexOf(16);
                    if(start < 0){
                        start = 0;
                    }
                    ShanShuiGridParam driftGridParam = new ShanShuiGridParam(16, start, true, true);
                    userData.setDriftGridParam(driftGridParam);
                    List<Integer> allGridList = new ArrayList<>();
                    int size = config.getGridInfoList().size();
                    for (int i = 1; i <= size; i++) {
                        allGridList.add(i);
                    }
                    userData.setNotTouchGrid(allGridList);
                    userData.setBuyRole(new ArrayList<>());
                    userData.setHelpTimes(config.getSHANSHUI_HELP_TIME());
//                    userData.setSilverCoin(config.getSHANSHUI_START_SILVER_COIN());
                    userData.setSilverUpdateTime(System.currentTimeMillis());
                    userData.setBeautyList(new ArrayList<>());
                    userDataMap.put(userId, userData);
                }
            }
        }
        return userData;
    }

    private Map<Integer, Object> teamLockerMap = new ConcurrentHashMap<>();

    public Object getTeamLocker(int teamId){
        if(!teamLockerMap.containsKey(teamId)){
            synchronized (teamLockerMap){
                if(!teamLockerMap.containsKey(teamId)){
                    teamLockerMap.put(teamId, new Object());
                }
            }
        }
        return teamLockerMap.get(teamId);
    }

    private Map<Long, Object> userLockerMap = new ConcurrentHashMap<>();

    public Object getUserLocker(long userId){
        if(!userLockerMap.containsKey(userId)){
            synchronized (userLockerMap){
                if(!userLockerMap.containsKey(userId)){
                    userLockerMap.put(userId, new Object());
                }
            }
        }
        return userLockerMap.get(userId);
    }

    //队伍十连锁
    private Map<Integer, Object> teamTenLockerMap = new ConcurrentHashMap<>();

    public Object getTeamTenLocker(int teamId){
        if(!teamTenLockerMap.containsKey(teamId)){
            synchronized (teamTenLockerMap){
                if(!teamTenLockerMap.containsKey(teamId)){
                    teamTenLockerMap.put(teamId, new Object());
                }
            }
        }
        return teamTenLockerMap.get(teamId);
    }

    public Object getLock() {
        return lock;
    }

    public CrossXingYouShanShuiData getShanShuiData() {
        return shanShuiData;
    }

    public void updateUserAbility(long serverId, long playerId, List<XingYouShanShuiProto.ShanShuiBeautyDetailInfo> detailList, boolean needBack) {
        CrossXingYouShanShuiUserData userData = getUserData(playerId);

        if(needBack){
            if(userData.getLastAbilityUpdateTime() > 0 && userData.getLastAbilityUpdateTime() > config.getActivityInfo().getBeginTime()){
                //同步间隔
                if(userData.getLastAbilityUpdateTime() + config.getSHANSHUI_POWER_COOL_TIME() * DateHelper.HOUR_SECONDS >  System.currentTimeMillis() / 1000){
                    XingYouShanShuiProto.ShanShuiUpdateBeautyAbilityRespMsg.Builder clientMsg = XingYouShanShuiProto.ShanShuiUpdateBeautyAbilityRespMsg.newBuilder();
                    clientMsg.setRet(GameErrorCode.E_XING_YOU_SHAN_SHUI_POWER_SYNC_CD);
                    clientMsg.setUpdateTime(userData.getLastAbilityUpdateTime());
                    MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_XING_YOU_SHAN_SHUI_UPDATE_BEAUTY, clientMsg));
                    return;
                }
            }
        }

        List<ShanShuiBeauty> beautyList = new ArrayList<>();
        int totalIntimacy = 0;
        int totalGlamour = 0;
        for (XingYouShanShuiProto.ShanShuiBeautyDetailInfo info : detailList) {
            ShanShuiBeauty beauty = new ShanShuiBeauty();
            beauty.setId(info.getBeautyId());
            beauty.setMacy(info.getMacy());
            beauty.setMour(info.getMour());
            beauty.setIc(info.getSkinId());
            beauty.setQ(info.getQuality());
            beautyList.add(beauty);
            totalGlamour += beauty.getMour();
            totalIntimacy += beauty.getMacy();
        }
        userData.setBeautyList(beautyList);
        if(needBack){
            userData.setLastAbilityUpdateTime(System.currentTimeMillis() / 1000);
            XingYouShanShuiProto.ShanShuiUpdateBeautyAbilityRespMsg.Builder clientMsg = XingYouShanShuiProto.ShanShuiUpdateBeautyAbilityRespMsg.newBuilder();
            clientMsg.setRet(0);
            clientMsg.setUpdateTime(userData.getLastAbilityUpdateTime());
            for (int i = 0; i < userData.getBeautyList().size(); i++) {
                ShanShuiBeauty beauty = userData.getBeautyList().get(i);
                XingYouShanShuiProto.ShanShuiBeautyDetailInfo.Builder builder = getBeautyBuilder(beauty);
                clientMsg.addBeauty(builder);
            }
            MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_XING_YOU_SHAN_SHUI_UPDATE_BEAUTY, clientMsg));

            //日志
            CrossAutoLogMgr.add(new LogCrossXingYouBeautySync(userData.getActivityId(), userData.getUserId(), userData.getTeamId(), totalIntimacy, totalGlamour, totalGlamour + totalIntimacy));
        }
    }

    public void notifyUploadBeautyData() {
        Map<Long, List<Long>> serverUserMap = new HashMap<>();
        for (Map.Entry<Long, CrossXingYouShanShuiUserData> entry : userDataMap.entrySet()) {
            CrossXingYouShanShuiUserData value = entry.getValue();
            //未组队也拉数据吧，测试说不能延迟
//            if(value.getTeamId() <= 0){
//                continue;
//            }
            if(value.getBeautyList() == null || value.getBeautyList().isEmpty()){
                UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(value.getUserId());
                if(userBaseInfo == null){
                    continue;
                }
                if(!serverUserMap.containsKey(userBaseInfo.getServerId())){
                    serverUserMap.put(userBaseInfo.getServerId(), new ArrayList<>());
                }
                serverUserMap.get(userBaseInfo.getServerId()).add(value.getUserId());
            }
        }

        for (Map.Entry<Long, List<Long>> entry : serverUserMap.entrySet()) {
            XingYouShanShuiProto.CrossShanShuiNotifyUpload.Builder builder = XingYouShanShuiProto.CrossShanShuiNotifyUpload.newBuilder();
            builder.addAllUserId(entry.getValue());
            MessageHelper.sendPacket(entry.getKey(), 0, YanQuMessageUtils.buildMessage(Protocol.S_XING_YOU_SHAN_SHUI_BATTLE_DATA_UPLOAD_NOTIFY, builder));
        }
    }

    public ConcurrentHashSet<Long> getInMapUserSet() {
        return inMapUserSet;
    }

    public void syncTimer() {

        syncUserRedDot();

        //同步妈祖数据
        boolean b = shanShuiData.isNeedSync().compareAndSet(true, false);
        if(b){
            XingYouShanShuiProto.ShanShuiTowerInfo.Builder towerInfoBuilder = getTowerInfoBuilder();
            XingYouShanShuiProto.ShanShuiReturnLighthouseNotify.Builder sync = XingYouShanShuiProto.ShanShuiReturnLighthouseNotify.newBuilder();
            sync.setTowerInfo(towerInfoBuilder);
            for (Long uid : inMapUserSet) {
                UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(uid);
                if(userBaseInfo == null){
                    continue;
                }
                MessageHelper.sendPacket(userBaseInfo.getServerId(), uid,
                        YanQuMessageUtils.buildMessage(Protocol.U_XING_YOU_SHAN_SHUI_RETURN_LIGHTHOUSE_NOTIFY, sync));
            }
        }

    }

    /**
     * 同步红点
     */
    private void syncUserRedDot() {
        try{
            //同步红点
            Set<Long> userSet = new HashSet<>();
            if(!needSyncRedDotUserMap.isEmpty()){
                ConcurrentHashSet<Long> tempUserMap = this.needSyncRedDotUserMap;
                this.needSyncRedDotUserMap = new ConcurrentHashSet<>();
                userSet.addAll(tempUserMap);
            }
            if(!needSyncRedDotTeamMap.isEmpty()){
                ConcurrentHashSet<Integer> tempTeamMap = this.needSyncRedDotTeamMap;
                this.needSyncRedDotTeamMap = new ConcurrentHashSet<>();
                for (int teamId : tempTeamMap) {
                    CommonTeam team = CommonTeamMgr.getTeam(config.getActivityInfo().getActivityId(), this.groupId, teamId);
                    if(team != null){
                        userSet.addAll(team.getMemberDataMap().keySet());
                    }
                }
            }
            if(!userSet.isEmpty()){
                for (Long uid : userSet) {
                    CrossXingYouShanShuiUserData userData = getUserData(uid);
                    if(userData.getTeamId() <= 0){
                        continue;
                    }
                    CommonTeam commonTeam = CommonTeamMgr.getTeam(config.getActivityInfo().getActivityId(), this.groupId, userData.getTeamId());
                    if(commonTeam != null){
                        CommonTeamUserData memberData = commonTeam.getMemberData(uid);
                        if(memberData != null){
                            String redValue = calUserRedValue(uid);
                            MessageHelper.sendPacket(memberData.getServerId(), uid, YanQuMessageUtils.buildMessage(Protocol.U_XING_YOU_SHAN_SHUI_SYNC_RED_DOT,
                                    XingYouShanShuiProto.ShanShuiRedDotNotify.newBuilder().setRedValue(redValue)));
                        }
                    }
                }
            }
        }catch (Exception e){
            CrossXingYouShanShuiMgr.getLogger().error("syncUserRedDot", e);
        }
    }

    private boolean initBeforeActivity = false;
    /**
     * 组队期前20分钟，初始地图数据（挑战格、衙门、建筑）
     */
    public void initBeforeActivity(){
//        if(initBeforeActivity){
//            return;
//        }

        Map<Integer, Integer> posGridMap = new HashMap<>();
        for (int i = 0; i < config.getSHANSHUI_MAP().size(); i++) {
            Integer gid = config.getSHANSHUI_MAP().get(i);
            if(gid == eXingYouGridTypes.Seventeen.getId()){
                posGridMap.put(i, gid);
            }
        }
        if(posGridMap.isEmpty()){
            return;
        }
        for (Map.Entry<Integer, CrossXingYouShanShuiTeamData> entry : teamDataMap.entrySet()) {
            CrossXingYouShanShuiTeamData teamData = entry.getValue();
            if(teamData.getTeamId() <= 0){
                continue;
            }
            for (Map.Entry<Integer, Integer> posEntry : posGridMap.entrySet()) {
                CrossXingYouShanShuiTeamMapData mapData = getCrossXingYouShanShuiTeamMapData(teamData.getTeamId(), posEntry.getKey());
                if(mapData.getTzUserId() <= 0){
                    synchronized (getTeamLocker(teamData.getTeamId())) {
                        if (mapData.getTzUserId() == 0) {
                            //随机一个玩家
                            mapData.setTzUserId(randomTzEmeny(teamData.getTeamId()));
                        }
                    }
                }
            }
        }
        initBeforeActivity = true;
    }

    /**
     * 检测漂泊超时
     */
    public void checkDriftTimeout(){
        if(userDataMap != null){
            long nowTime = System.currentTimeMillis();
            XingYouShanShuiGridInfo gridInfo = config.getGridInfo(eXingYouGridTypes.Sixteen.getId());
            if(gridInfo == null){
                return;
            }
            for (Map.Entry<Long, CrossXingYouShanShuiUserData> entry : userDataMap.entrySet()) {
                CrossXingYouShanShuiUserData userData = entry.getValue();
                if(userData.isDrift()){
                    synchronized (getUserLocker(userData.getUserId())){
                        if(!userData.isDrift()){
                            continue;
                        }
                        if(userData.getStartDriftTime() <= 0){
                            continue;
                        }
                        if(userData.getDriftEndType() < -1){
                            //已结算过
                            continue;
                        }
                        if(nowTime <  userData.getStartDriftTime() + gridInfo.getParam().get(4) * DateHelper.SECOND_MILLIONS){
                            //未到时间
                            continue;
                        }
                        //结算漂泊信息
                        userData.setDriftEndType(-5);
                    }
                }
            }
        }
    }

    /**
     * 协战列表
     */
    public void getOperationList(long serverId, long playerId, int page) {
        CrossXingYouShanShuiUserData userData = getUserData(playerId);
        if(userData.getTeamId() <= 0){
            return;
        }
        CommonTeamActivity teamActivity = CommonTeamMgr.getActivity(config.getActivityInfo().getActivityId(), this.groupId);
        List<CrossXingYouTargetMarkData> list = getTodoMarkDataList(userData);
        XingYouShanShuiProto.ShanShuiJointOperationListRsp.Builder clientMsg = XingYouShanShuiProto.ShanShuiJointOperationListRsp.newBuilder();
        clientMsg.setRet(0);
        clientMsg.setHelpTimes(userData.getHelpTimes());
        int pageSize = 20;
        int start = (page - 1)* pageSize;
        int end = start + pageSize;
        end = Math.min(end, list.size());
        CommonTeam myTeam = teamActivity.getTeam(userData.getTeamId());
        int memberSize = myTeam.getMemberDataMap().size();
        long nowTimes = System.currentTimeMillis();
        if(start < list.size()){
            List<CrossXingYouTargetMarkData> subList = list.subList(start, end);
            for (CrossXingYouTargetMarkData data : subList) {
                XingYouShanShuiProto.ShanShuiChallengePlayerInfo.Builder builder = getChallengeBuilder(teamActivity, memberSize, nowTimes, data, userData.getUserId());
                clientMsg.addChallengePlayerInfo(builder);
            }
        }

        MessageHelper.sendPacket(serverId, userData.getUserId(), YanQuMessageUtils.buildMessage(Protocol.U_XING_YOU_SHAN_SHUI_JOINT_OPERATION_LIST, clientMsg));

        needSyncRedDotUserMap.add(userData.getUserId());
    }

    /**
     * 协战battle
     */
    public int challengeOperation(long serverId, long playerId, long markId) {
        CrossXingYouShanShuiUserData userData = getUserData(playerId);
        if(userData.getTeamId() <= 0){
            return GameErrorCode.E_XING_YOU_SHAN_SHUI_PLAYER_NO_TEAM;
        }
        XingYouShanShuiProto.ShanShuiBattleRecordMsg.Builder builder;
        CommonTeamActivity teamActivity = CommonTeamMgr.getActivity(config.getActivityInfo().getActivityId(), this.groupId);
        if(teamActivity == null){
            return GameErrorCode.E_COMMON_TEAM_TEAM_ACTIVITY_NOT_EXIST;
        }
        CrossXingYouTargetMarkData data = null;
        XingYouShanShuiProto.ShanShuiJointOperationRsp.Builder respMsg = XingYouShanShuiProto.ShanShuiJointOperationRsp.newBuilder();
        synchronized (getTeamLocker(userData.getTeamId())){
            //次数
            if(userData.getHelpTimes() <= 0){
                return GameErrorCode.E_XING_YOU_SHAN_SHUI_HELP_TIMES_NO_ENOUGH;
            }
            List<CrossXingYouTargetMarkData> list = teamMarkMap.get(userData.getTeamId());
            if(list == null || list.isEmpty()){
                return GameErrorCode.E_XING_YOU_SHAN_SHUI_INFO_OUT_TIME;
            }
            for (int i = 0; i < list.size(); i++) {
                CrossXingYouTargetMarkData markData = list.get(i);
                if(markData.getId() == markId){
                    data = markData;
                    break;
                }
            }
            if(data == null){
                return GameErrorCode.E_XING_YOU_SHAN_SHUI_INFO_OUT_TIME;
            }
            if(data.getUserId() == playerId){
                return -1;
            }
            if(data.getTargetHp() <= 0){
                return GameErrorCode.E_XING_YOU_SHAN_SHUI_HELP_WIN;
            }
            if(data.getTzList().contains(playerId)){
                return GameErrorCode.E_XING_YOU_SHAN_SHUI_HELP_DONE;
            }
            userData.setHelpTimes(userData.getHelpTimes() - 1);
            long beforeHp = data.getTargetHp();
            builder = battle(playerId, data.getTargetUserId(), new ArrayList<>(), (int) data.getTargetHp());
            if(builder.getIsWin()){
                data.setTargetHp(0);
            }else {
                data.setTargetHp(builder.getEnemyHp());
            }
            data.getTzList().add(playerId);

            //协战奖励
            Property property = new Property();
            XingYouShanShuiGridInfo gridInfo = config.getGridInfo(eXingYouGridTypes.Seventeen.getId());
            if(gridInfo != null && !"0".equals(gridInfo.getReward2())){
                property = PropertyHelper.parseStringToProperty(gridInfo.getReward2());
                BigDecimal decimal = BigDecimal.valueOf(beforeHp - data.getTargetHp()).divide(BigDecimal.valueOf(data.getMaxTargetHp()), 3, BigDecimal.ROUND_UP);
                property.rideProperty(decimal);
                respMsg.setReward(PropertyHelper.parsePropertyToString(property));
            }

            addReward(userData, property, false, 10);

            addMarkDataUpdate(data);

            CrossXingYouShanShuiUserData tzUserData = getUserData(data.getTargetUserId());
            LogCrossXingYouBattle log = new LogCrossXingYouBattle(
                    userData.getActivityId(),
                    userData.getUserId(),
                    userData.getTeamId(),
                    0,
                    0,
                    userData.getMapTeamId(),
                    data.getTargetUserId(),
                    tzUserData.getTeamId(),
                    2,
                    builder.getPlayers(0).getMaxHp(),
                    builder.getPlayers(1).getHp() - builder.getEnemyHp(),
                    builder.getEnemyHp(),
                    builder.getIsWin() ? 1 : 0,
                    property.getCountByGoodsId(getConfig().getSHANSHUI_SILVER_COIN_ID()).intValue(),
                    property.getCountByGoodsId(getConfig().getSHANSHUI_GOLD_COIN_ID()).intValue(),
                    PropertyHelper.parsePropertyToString(property)
            );
            CrossAutoLogMgr.add(log);
        }

        CommonTeam myTeam = teamActivity.getTeam(userData.getTeamId());
        long nowTimes = System.currentTimeMillis();
        int memberSize = myTeam.getMemberDataMap().size();
        respMsg.setRet(0);
        respMsg.setIsWin(builder.getIsWin());
        respMsg.setHpPercent(builder.getEnemyHp());
        XingYouShanShuiProto.ShanShuiChallengePlayerInfo.Builder challengeBuilder = getChallengeBuilder(teamActivity, memberSize, nowTimes, data, userData.getUserId());
        respMsg.setChallengePlayerInfo(challengeBuilder);
        respMsg.setBattleRecord(builder);

        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.S_XING_YOU_SHAN_SHUI_JOINT_OPERATION_FROM_CROSS, respMsg));

        syncShanShuiPropNotify(userData.getTeamId(), Arrays.asList(XingYouShanShuiProto.PROP.TEAM_SILVER_VALUE, XingYouShanShuiProto.PROP.TEAM_CUL_SILVER_VALUE));
        needSyncRedDotTeamMap.add(userData.getTeamId());
        return 0;
    }

    /**
     * 协战奖励领取
     */
    public void getOperationReward(long serverId, long playerId, long markId) {
        CrossXingYouShanShuiUserData userData = getUserData(playerId);
        if(userData.getTeamId() <= 0){
            return;
        }
        CommonTeamActivity teamActivity = CommonTeamMgr.getActivity(config.getActivityInfo().getActivityId(), this.groupId);
        if(teamActivity == null){
            return;
        }
        CrossXingYouTargetMarkData data = null;
        synchronized (getTeamLocker(userData.getTeamId())){
            List<CrossXingYouTargetMarkData> list = teamMarkMap.get(userData.getTeamId());
            if(list == null || list.isEmpty()){
                return;
            }
            for (int i = 0; i < list.size(); i++) {
                CrossXingYouTargetMarkData markData = list.get(i);
                if(markData.getId() == markId && markData.getUserId() == playerId){
                    data = markData;
                    break;
                }
            }
            if(data == null){
                return;
            }
            if(data.getGetReward() == 1){
                return;
            }
            data.setGetReward(1);
            addMarkDataUpdate(data);
            //随机奖励
            String reward = getCheReward();
            XingYouShanShuiProto.ShanShuiJointOperationAwardRsp.Builder respMsg = XingYouShanShuiProto.ShanShuiJointOperationAwardRsp.newBuilder();
            respMsg.setRet(0);
            respMsg.setAward(reward);
            MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.S_XING_YOU_SHAN_SHUI_JOINT_OPERATION_AWARD_FROM_CROSS, respMsg));

            needSyncRedDotUserMap.add(playerId);
        }
    }

    /**
     * 玩家登录
     */
    public void userLoginByCmd(long serverId, long userId, XingYouShanShuiProto.CrossShanShuiUserLoginReq req) {
        if(needSyncRedDotUserMap != null){
            needSyncRedDotUserMap.add(userId);
        }
        //其他逻辑
    }

    /**
     * 挑战成功奖励
     */
    public String getCheReward() {
        String reward = "";
        XingYouShanShuiGridInfo gridInfo = config.getGridInfo(eXingYouGridTypes.Seventeen.getId());
        if(gridInfo != null){
            Property property = RandomWeightConfigHelper.getProperty(gridInfo.getReward1());
            if(property != null) {
                reward = PropertyHelper.parsePropertyToString(property);
            }
        }
        return reward;
    }

    public void syncDriftState(long userId, int teamId, int state){
        try {
            if (teamId <= 0) {
                return;
            }
            XingYouShanShuiProto.ShanShuiDriftInfoSync.Builder clientMsg = XingYouShanShuiProto.ShanShuiDriftInfoSync.newBuilder();
            if (state == 1) {
                XingYouShanShuiProto.ShanShuiMemberInfo.Builder memberBuilder = getMemberBuilder(getUserData(userId), true);
                if (memberBuilder != null) {
                    clientMsg.setJoin(memberBuilder);
                }
            } else {
                clientMsg.setQuit(userId);
            }
            CrossXingYouShanShuiTeamData teamData = getTeamData(teamId);
            ArrayList<Long> userIdList = new ArrayList<>(teamData.getVisitorMap().keySet());
            userIdList.remove(userId);
//            CrossXingYouShanShuiMgr.getLogger().error("漂泊队友 {}", teamData.getVisitorMap().keySet());
            if(userIdList.isEmpty()){
                return;
            }
            MessageHelper.sendPacketToAll(Protocol.U_XING_YOU_SHAN_SHUI_DRIFT_STATE_SYNC, clientMsg, userIdList);
        }catch (Exception e){
            CrossXingYouShanShuiMgr.getLogger().error("", e);
        }
    }

    /**
     * 队伍日志
     */
    public void teamLogList(long serverId, long playerId, int page) {
        CrossXingYouShanShuiUserData userData = getUserData(playerId);
        if(userData.getTeamId() <= 0){
            return;
        }
        List<CrossXingYouShanShuiTeamActionLogData> list = teamLogMap.get(userData.getTeamId());
        XingYouShanShuiProto.ShanShuiTeamLogRsp.Builder clientMsg = XingYouShanShuiProto.ShanShuiTeamLogRsp.newBuilder();
        clientMsg.setRet(0);
        if(list != null && !list.isEmpty()) {
            List<CrossXingYouShanShuiTeamActionLogData> poolList = new ArrayList<>();
            int pageSize = 20;
            //总条数
            int total = list.size();
            //总页数
            //int totalPage = total / pageSize + 1;
            int end = (total - 1) - (page - 1) * pageSize;
            int start = end - pageSize + 1;
            end = Math.min(end, total - 1);
            start = Math.max(0, start);
            for (int i = end; i >= 0 && i >= start; i--){
                poolList.add(list.get(i));
            }
            clientMsg.setRet(0);
            for (CrossXingYouShanShuiTeamActionLogData logData : poolList) {
                XingYouShanShuiProto.ShanShuiTeamLogInfo.Builder builder = XingYouShanShuiProto.ShanShuiTeamLogInfo.newBuilder();
                builder.setPlayerId(logData.getUserId());
                builder.setLogType(logData.getLogType());
                builder.setTime(logData.getLogTime());
                builder.setId(logData.getId());
                UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(logData.getUserId());
                if (userBaseInfo != null) {
                    builder.setAppearanceId(userBaseInfo.getDecoration());
                }
                //参数
                builder.setParam(logData.getParam());
                builder.setAward(logData.getReward() == null ? "" : logData.getReward());
                builder.setIsDrift(logData.getDrift() == 1);
                //奖励
                clientMsg.addLogInfoList(builder);
            }
        }
        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_XING_YOU_SHAN_SHUI_TEAM_LOG, clientMsg));
    }

    public void getUserSimpleData(long serverId, long playerId, long lastSyncTeamTime) {
        CrossXingYouShanShuiUserData userData = getUserData(playerId);
        if(userData.getTeamId() <= 0){
            return;
        }
        CrossXingYouShanShuiTeamData teamData = getTeamData(userData.getTeamId());
        XingYouShanShuiProto.ShanShuiGetUserSimpleDataRsp.Builder clientMsg = XingYouShanShuiProto.ShanShuiGetUserSimpleDataRsp.newBuilder();
        clientMsg.setRet(0);
        clientMsg.setEnergyUse(userData.getUseEnergy());
        clientMsg.setTeamEnergyUse(getTeamTotalUseEnergy(userData.getTeamId()));
        clientMsg.setWishShareLastGetTime(userData.getWishShareLastGetTime());
        clientMsg.setLastSyncTeamTime(userData.getLastAbilityUpdateTime());
        clientMsg.setSilverCoin(teamData.getSilverCoin());
        clientMsg.setSilverCoinTotal(teamData.getSilverCoinTotal());
        int size = config.getGridInfoList().size();
        for (int i = 1; i <= size; i++) {
            if(userData.getNotTouchGrid().contains(i)){
                continue;
            }
            clientMsg.addGridType(i);
        }
        if(userData.getBeautyList() != null) {
            for (int i = 0; i < userData.getBeautyList().size(); i++) {
                ShanShuiBeauty beauty = userData.getBeautyList().get(i);
                XingYouShanShuiProto.ShanShuiBeautyDetailInfo.Builder builder = getBeautyBuilder(beauty);
                clientMsg.addBeauty(builder);
            }
        }
        List<CrossXingYouTargetMarkData> list = getTodoMarkDataList(userData);
        for (CrossXingYouTargetMarkData markData : list) {
            if(markData.getUserId() != userData.getUserId()){
                clientMsg.addCanHelpId(markData.getId());
            }
        }
        clientMsg.addAllBuyRoleId(userData.getBuyRole());

        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_XING_YOU_SHAN_SHUI_USER_SIMPLE_DATA, clientMsg));
    }

    public void addCrossXingYouShanShuiTeamActionLogData(CrossXingYouShanShuiTeamActionLogData logData){
        List<CrossXingYouShanShuiTeamActionLogData> list = teamLogMap.get(logData.getTeamId());
        if(list == null){
            synchronized (teamLogMap){
                list = teamLogMap.get(logData.getTeamId());
                if(list == null){
                    list = new ArrayList<>();
                    teamLogMap.put(logData.getTeamId(), list);
                }
            }
        }
        synchronized (list){
            if(logData.getId() == 0){
                logData.setId(maxActionId.incrementAndGet());
            }
            if(list.size() >= config.getSHANSHUI_LOG_LIMIT()){
                list.remove(0);
            }
            list.add(logData);
        }
        synchronized (teamLogUpdateList){
            teamLogUpdateList.add(logData);
        }
    }

    public CrossXingYouShanShuiTeamActionLogData findEvent3Log(CrossXingYouShanShuiUserData userData){
        List<CrossXingYouShanShuiTeamActionLogData> dataList = teamLogMap.get(userData.getTeamId());
        if(dataList == null){
            return null;
        }
        for (int i = 0; i < dataList.size(); i++) {
            CrossXingYouShanShuiTeamActionLogData data = dataList.get(i);
            if(data.getEventId() == 3 && data.getUserId() == userData.getUserId()){
                return data;
            }
        }
        return null;
    }

    public void addCrossXingYouTargetMarkData(CrossXingYouTargetMarkData markData){
        List<CrossXingYouTargetMarkData> list = teamMarkMap.get(markData.getTeamId());
        if(list == null){
            synchronized (teamMarkMap){
                list = teamMarkMap.get(markData.getTeamId());
                if(list == null){
                    list = new ArrayList<>();
                    teamMarkMap.put(markData.getTeamId(), list);
                }
            }
        }
        synchronized (list){
            //需要领奖，定时器来操作移除
//            if(list.size() >= config.getSHANSHUI_BATTLE_LOG_LIMIT()){
//                list.remove(0);
//            }
            if(markData.getId() == 0){
                markData.setId(maxMarkId.incrementAndGet());
            }
            list.add(markData);
        }
        addMarkDataUpdate(markData);
    }

    private void addMarkDataUpdate(CrossXingYouTargetMarkData markData) {
        synchronized (teamMarkUpdateList){
            teamMarkUpdateList.add(markData);
        }
    }

    public void addCrossXingYouShanShuiCatchLogData(CrossXingYouShanShuiCatchLogData data){
        List<CrossXingYouShanShuiCatchLogData> list = teamCatchDataMap.get(data.getTeamId());
        if(list == null){
            synchronized (teamCatchDataMap){
                list = teamCatchDataMap.get(data.getTeamId());
                if(list == null){
                    list = new ArrayList<>();
                    teamCatchDataMap.put(data.getTeamId(), list);
                }
            }
        }
        synchronized (list){
            if(data.getId() == 0){
                data.setId(maxCatchLogId.incrementAndGet());
            }
            list.add(data);
        }
        synchronized (logCatchDataUpdateList){
            logCatchDataUpdateList.add(data);
        }
    }

    public void addCrossXingYouShanShuiWishRewardData(CrossXingYouShanShuiWishRewardData data){
        List<CrossXingYouShanShuiWishRewardData> list = teamWishRewardMap.get(data.getTeamId());
        if(list == null){
            synchronized (teamWishRewardMap){
                list = teamWishRewardMap.get(data.getTeamId());
                if(list == null){
                    list = new ArrayList<>();
                    teamWishRewardMap.put(data.getTeamId(), list);
                }
            }
        }
        synchronized (list){
            list.add(data);
        }
        addWishDataUpdate(data);
    }

    private void addWishDataUpdate(CrossXingYouShanShuiWishRewardData data) {
        synchronized (wishRewardDataUpdateList){
            wishRewardDataUpdateList.add(data);
        }
    }

    public void addCrossXingYouShanShuiBuildingLogData(CrossXingYouShanShuiBuildingLogData logData){
        List<CrossXingYouShanShuiBuildingLogData> list = buildLogMap.get(logData.getTeamId());
        if(list == null){
            synchronized (buildLogMap){
                list = buildLogMap.get(logData.getTeamId());
                if(list == null){
                    list = new ArrayList<>();
                    buildLogMap.put(logData.getTeamId(), list);
                }
            }
        }
        synchronized (list){
            if(logData.getId() == 0){
                logData.setId(maxBuildLogId.incrementAndGet());
            }
            list.add(logData);
        }
        synchronized (buildingLogDataUpdateList){
            buildingLogDataUpdateList.add(logData);
        }
    }

    /**
     * 查看小行囊
     */
    public void viewTravellingBag(long serverId, long playerId) {
        CrossXingYouShanShuiUserData userData = getUserData(playerId);
        if(userData.getTeamId() <= 0){
            return;
        }

        XingYouShanShuiProto.ShanShuiTravellingBagRsp.Builder clientMsg = XingYouShanShuiProto.ShanShuiTravellingBagRsp.newBuilder();
        clientMsg.setRet(0);
        synchronized (getTeamLocker(userData.getTeamId())){
            if(userData.getWishShareValue() > 0){
                clientMsg.setWishReward(config.getSHANSHUI_GOLD_COIN_ID() + "=" + userData.getWishShareValue());
                userData.setWishShareValue(0);
            }
            if(userData.getCaptorReward() != null && !userData.getCaptorReward().isNothing()){
                clientMsg.setCatchReward(PropertyHelper.parsePropertyToString(userData.getCaptorReward()));
                userData.setCaptorReward(new Property());
            }
        }
        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_XING_YOU_SHAN_SHUI_VIEW_TRAVELLING_BAG, clientMsg));
    }

    private XingYouShanShuiProto.ShanShuiBeautyDetailInfo.Builder getBeautyBuilder(ShanShuiBeauty beauty) {
        XingYouShanShuiProto.ShanShuiBeautyDetailInfo.Builder builder = XingYouShanShuiProto.ShanShuiBeautyDetailInfo.newBuilder();
        builder.setBeautyId(beauty.getId());
        builder.setSkinId(beauty.getIc());
        builder.setMour(beauty.getMour());
        builder.setMacy(beauty.getMacy());
//        builder.setAdd(beauty.getA());
        builder.setQuality(beauty.getQ());
        return builder;
    }

    private XingYouShanShuiProto.ShanShuiMemberInfo.Builder getMemberBuilder(CrossXingYouShanShuiUserData member, boolean drift) {
        if(member == null){
            return null;
        }
        XingYouShanShuiProto.ShanShuiMemberInfo.Builder builder = XingYouShanShuiProto.ShanShuiMemberInfo.newBuilder();
        builder.setPlayerId(member.getUserId());
        builder.setPosition(member.getGridParam().getMapIndex());
        builder.setPosition(member.getGridParam().getMapIndex());
        if(drift){
            builder.setPosition(member.getDriftGridParam().getMapIndex());
            builder.setPosition(member.getDriftGridParam().getMapIndex());
        }
        builder.setRoleId(member.getRoleId());
        builder.setSilverCoin((int)member.getSilverCoinTotal());
        UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(member.getUserId());
        if(userBaseInfo != null){
            builder.setPlayerInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
            builder.setAppearanceId(userBaseInfo.getDecoration());
        }
        return builder;
    }

    private void syncMemberMove(List<Long> memberList, XingYouShanShuiProto.ShanShuiMoveInfo moveInfo, XingYouShanShuiProto.ShanShuiMapInfo mapInfo) {
        XingYouShanShuiProto.ShanShuiMemberMoveNotify.Builder notify = XingYouShanShuiProto.ShanShuiMemberMoveNotify.newBuilder();
        notify.setMoveInfo(moveInfo);
        notify.setMapInfo(mapInfo);
        for (Long uid : memberList) {
            MessageHelper.sendPacket(Protocol.U_XING_YOU_SHAN_SHUI_MEMBER_MOVING_NOTIFY, notify, uid);
        }
    }

    private void syncDriftMoveInfo(int driftMapTeamId, List<Long> driftMemberList, XingYouShanShuiProto.ShanShuiMoveInfo moveInfo) {
        XingYouShanShuiProto.ShanShuiDriftMemberMoveNotify.Builder notify = XingYouShanShuiProto.ShanShuiDriftMemberMoveNotify.newBuilder();
        if(moveInfo != null){
            notify.setMoveInfo(moveInfo);
        }
        XingYouShanShuiProto.ShanShuiMapInfo.Builder mapInfoBuilder = getMapInfoBuilder(driftMapTeamId);
        if(mapInfoBuilder != null) {
            notify.setMapInfo(mapInfoBuilder);
        }
        for (Long uid : driftMemberList) {
            MessageHelper.sendPacket(Protocol.U_XING_YOU_SHAN_SHUI_DRIFT_MEMBER_MOVING_NOTIFY, notify, uid);
        }
    }

    private XingYouShanShuiProto.ShanShuiDriftInfo.Builder getDriftInfo(int teamId, CrossXingYouShanShuiUserData userData) {
        if(userData.getTeamId() <= 0){
            return null;
        }
        XingYouShanShuiProto.ShanShuiDriftInfo.Builder builder = XingYouShanShuiProto.ShanShuiDriftInfo.newBuilder();
        CommonTeam team = CommonTeamMgr.getTeam(config.getActivityInfo().getActivityId(), this.groupId, teamId);
        if(team != null){
            builder.setTeamName(team.getTeamName());
            builder.setTeamId(teamId);
        }
        CrossXingYouShanShuiTeamData teamData = getTeamData(teamId);
        if(teamData != null){
            ArrayList<Long> list = new ArrayList<>(teamData.getVisitorMap().keySet());
            for (Long uid : list) {
                XingYouShanShuiProto.ShanShuiMemberInfo.Builder memberBuilder = getMemberBuilder(getUserData(uid), true);
                if(memberBuilder != null){
                    builder.addDriftMemberInfo(memberBuilder);
                }
            }

        }
        if(teamId > 0) {
            XingYouShanShuiProto.ShanShuiMapInfo.Builder driftMapInfo = getMapInfoBuilder(teamId);
            if(driftMapInfo != null) {
                CrossXingYouShanShuiTeamData myTeam = getTeamData(userData.getTeamId());
                driftMapInfo.setSilverCoin((int) myTeam.getSilverCoin());
                driftMapInfo.setSilverCoinTotal((int) myTeam.getSilverCoinTotal());
                builder.setDriftMapInfo(driftMapInfo);
            }
        }else {
            CrossXingYouShanShuiMgr.getLogger().info("{} {} 漂泊状态时，没有队伍信息", config.getActivityInfo().getActivityId(), userData.getUserId());
        }
        XingYouShanShuiProto.ShanShuiDriftPlayerInfo.Builder driftPlayerInfoBuilder = XingYouShanShuiProto.ShanShuiDriftPlayerInfo.newBuilder();
        driftPlayerInfoBuilder.setDriftDice(userData.getDriftTimes());
        driftPlayerInfoBuilder.setAward(PropertyHelper.parsePropertyToString(userData.getDriftReward()));
        driftPlayerInfoBuilder.setDriftStartTime(userData.getStartDriftTime());
        driftPlayerInfoBuilder.setPlayerId(userData.getUserId());
        driftPlayerInfoBuilder.setPosition(userData.getDriftGridParam().getMapIndex());
        driftPlayerInfoBuilder.setCurEventInfo(getCurEventInfoBuilder(userData.getDriftGridParam()));
        builder.setDriftPlayerInfo(driftPlayerInfoBuilder);

        return builder;
    }

    private XingYouShanShuiProto.ShanShuiMapInfo.Builder getMapInfoBuilder(int teamId) {
        if(teamId <= 0){
            return null;
        }
        CrossXingYouShanShuiTeamData teamData = getTeamData(teamId);
        XingYouShanShuiProto.ShanShuiMapInfo.Builder mapInfoBuilder = XingYouShanShuiProto.ShanShuiMapInfo.newBuilder();
        mapInfoBuilder.setUpdateTime(System.currentTimeMillis());
        Map<Integer, CrossXingYouShanShuiTeamMapData> mapDataMap = teamMapDataMap.get(teamId);
        if(mapDataMap != null){
            for (Map.Entry<Integer, CrossXingYouShanShuiTeamMapData> entry : mapDataMap.entrySet()) {
                CrossXingYouShanShuiTeamMapData mapData = entry.getValue();
                if(config.isBuildGrid(mapData.getGridId())){
                    XingYouShanShuiProto.ShanShuiBuildingInfo.Builder buildingInfoBuilder = XingYouShanShuiProto.ShanShuiBuildingInfo.newBuilder();
                    buildingInfoBuilder.setGridId(mapData.getGridId());
                    buildingInfoBuilder.setPosition(mapData.getMapIndex());
                    buildingInfoBuilder.setBuildingLevel(mapData.getBuildLv());
                    buildingInfoBuilder.setBuildingState(mapData.getCloseTimes());
                    mapInfoBuilder.addBuildingInfoList(buildingInfoBuilder);
                }
            }
        }
        mapInfoBuilder.setUseEnergyTotal(getTeamTotalUseEnergy(teamId));
        mapInfoBuilder.setSilverCoin((int)teamData.getSilverCoin());
        mapInfoBuilder.setSilverCoinTotal((int)teamData.getSilverCoinTotal());

        Map<Integer, CrossXingYouShanShuiTeamMapData> dataMap = getCrossXingYouShanShuiTeamMapData(teamId);
        if(dataMap != null){
            for (Map.Entry<Integer, CrossXingYouShanShuiTeamMapData> entry : dataMap.entrySet()) {
                CrossXingYouShanShuiTeamMapData value = entry.getValue();
                long tzUserId = value.getTzUserId();
                if(value.getGridId() == eXingYouGridTypes.Seventeen.getId() && tzUserId > 0){
                    UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(tzUserId);
                    if(userBaseInfo != null){
                        XingYouShanShuiProto.ShanShuiChallengePlayerMapInfo.Builder builder = XingYouShanShuiProto.ShanShuiChallengePlayerMapInfo.newBuilder();
                        builder.setPosition(value.getMapIndex());
                        builder.setHeadInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
                        builder.setPlayerId(value.getTzUserId());
                        CrossXingYouShanShuiUserData shuiUserData = getUserData(tzUserId);
                        for (int i = 0; i < shuiUserData.getBeautyList().size(); i++) {
                            ShanShuiBeauty beauty = shuiUserData.getBeautyList().get(i);
                            builder.setTotalPower(builder.getTotalPower() + beauty.getTotal());
                        }
                        mapInfoBuilder.addChallengePlayerInfoList(builder);
                    }
                }
            }
        }
        for (int i = 0; i < teamData.getCaptorList().size(); i++) {
            mapInfoBuilder.addMaritimeCustomsAdministratorPosition(teamData.getCaptorList().get(i));
        }

        XingYouShanShuiProto.ShanShuiTradeShipInfo.Builder shipBuilder = XingYouShanShuiProto.ShanShuiTradeShipInfo.newBuilder();
        shipBuilder.setProgress(teamData.getWishValue());
        shipBuilder.setRound(teamData.getWishRound());
        shipBuilder.setAddedProgress(0);
        mapInfoBuilder.setTradeShipInfo(shipBuilder);

        XingYouShanShuiProto.ShanShuiTowerInfo.Builder towerInfoBuilder = getTowerInfoBuilder();

        mapInfoBuilder.setTowerInfo(towerInfoBuilder.build());

        return mapInfoBuilder;
    }

    private XingYouShanShuiProto.ShanShuiTowerInfo.Builder getTowerInfoBuilder() {
        XingYouShanShuiProto.ShanShuiTowerInfo.Builder towerInfoBuilder = XingYouShanShuiProto.ShanShuiTowerInfo.newBuilder();
        long userId = shanShuiData.getUserId();
        if(userId > 0){
            CrossXingYouShanShuiUserData userData = getUserData(userId);
            towerInfoBuilder.setTeamId(userData.getTeamId());
            towerInfoBuilder.setDeclare(userData.getDeclaration());
            CommonTeamActivity activity = CommonTeamMgr.getActivity(config.getActivityInfo().getActivityId(), this.groupId);
            if(activity != null){
                CommonTeam team = activity.getTeam(userData.getTeamId());
                if(team != null){
                    towerInfoBuilder.setTeamName(team.getTeamName());
                }
            }
            UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(userId);
            if(userBaseInfo != null){
                towerInfoBuilder.setHeadInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
            }
        }
        return towerInfoBuilder;
    }

    /**
     * 同步队伍数据给玩家
     */
    private void syncTeamData(CrossXingYouShanShuiUserData userData, boolean allTeam) {
        if(userData.getTeamId() <= 0){
            return;
        }
        CrossXingYouShanShuiTeamData teamData = getTeamData(userData.getTeamId());
        XingYouShanShuiProto.CrossShanShuiTeamDataSync.Builder sync = XingYouShanShuiProto.CrossShanShuiTeamDataSync.newBuilder();
        sync.setTotalEnergy(getTeamTotalUseEnergy(userData.getTeamId()));
        sync.setTotalSilver(teamData.getSilverCoinTotal());
        sync.addUserId(userData.getUserId());
        List<Long> serverIdList = new ArrayList<>();
        if(allTeam){
            CommonTeamActivity activity = CommonTeamMgr.getActivity(config.getActivityInfo().getActivityId(), this.groupId);
            if(activity != null){
                CommonTeam team = activity.getTeam(userData.getTeamId());
                if(team != null){
                    for (Map.Entry<Long, CommonTeamUserData> entry : team.getMemberDataMap().entrySet()) {
                        if(inMapUserSet.contains(entry.getKey())){
                            continue;
                        }
                        if(!sync.getUserIdList().contains(entry.getKey())){
                            sync.addUserId(entry.getKey());
                        }
                        CommonTeamUserData value = entry.getValue();
                        if(!serverIdList.contains(value.getServerId())){
                            serverIdList.add(value.getServerId());
                        }
                    }
                }
            }
        }else {
            UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(userData.getUserId());
            if(userBaseInfo != null){
                serverIdList.add(userBaseInfo.getServerId());
            }
        }
        for (Long sid : serverIdList) {
            MessageHelper.sendPacket(sid, 0, YanQuMessageUtils.buildMessage(Protocol.S_XING_YOU_SHAN_SHUI_TEAM_DATA_SYNC, sync));
        }
        if(allTeam){
            syncShanShuiPropNotify(sync.getUserIdList(), userData.getTeamId(), Arrays.asList(XingYouShanShuiProto.PROP.TEAM_SILVER_VALUE, XingYouShanShuiProto.PROP.TEAM_CUL_SILVER_VALUE));
        }
    }

    public void syncShanShuiPropNotify(List<Long> userIdList, int teamId, List<Integer> typeList) {
        XingYouShanShuiProto.ShanShuiPropNotify.Builder syncBuilder = XingYouShanShuiProto.ShanShuiPropNotify.newBuilder();
        CrossXingYouShanShuiTeamData teamData = getTeamData(teamId);

        XingYouShanShuiProto.ShanShuiPropInfo.Builder builder;
        if(typeList.contains(XingYouShanShuiProto.PROP.TEAM_SILVER_VALUE)){
            builder = XingYouShanShuiProto.ShanShuiPropInfo.newBuilder();
            builder.setType(XingYouShanShuiProto.PROP.TEAM_SILVER_VALUE);
            builder.setValue(String.valueOf(teamData.getSilverCoin()));
            syncBuilder.addProps(builder);
        }
        if(typeList.contains(XingYouShanShuiProto.PROP.TEAM_CUL_SILVER_VALUE)) {
            builder = XingYouShanShuiProto.ShanShuiPropInfo.newBuilder();
            builder.setType(XingYouShanShuiProto.PROP.TEAM_CUL_SILVER_VALUE);
            builder.setValue(String.valueOf(teamData.getSilverCoinTotal()));
            syncBuilder.addProps(builder);
        }
        if(typeList.contains(XingYouShanShuiProto.PROP.YA_MEN_POLICE_VALUE)) {
            builder = XingYouShanShuiProto.ShanShuiPropInfo.newBuilder();
            builder.setType(XingYouShanShuiProto.PROP.YA_MEN_POLICE_VALUE);
            //位置
            builder.setValue(StringUtils.listToString(teamData.getCaptorList(), ","));
            syncBuilder.addProps(builder);
        }
        if(typeList.contains(XingYouShanShuiProto.PROP.YA_MEN_SILVER_VALUE)) {
            builder = XingYouShanShuiProto.ShanShuiPropInfo.newBuilder();
            builder.setType(XingYouShanShuiProto.PROP.YA_MEN_SILVER_VALUE);
            builder.setValue(String.valueOf(teamData.getCaptorReward()));
            syncBuilder.addProps(builder);
        }
        if(typeList.contains(XingYouShanShuiProto.PROP.QI_YUAN_PROGRESS_VALUE)) {
            builder = XingYouShanShuiProto.ShanShuiPropInfo.newBuilder();
            builder.setType(XingYouShanShuiProto.PROP.QI_YUAN_PROGRESS_VALUE);
            builder.setValue("1");
            syncBuilder.addProps(builder);
        }
        for (int gid : typeList) {
            XingYouShanShuiGridInfo gridInfo = config.getGridInfo(gid);
            //是建筑
            if(gridInfo != null && gridInfo.getType() == 2){
                builder = XingYouShanShuiProto.ShanShuiPropInfo.newBuilder();
                int i = config.getSHANSHUI_MAP().indexOf(gid);
                if(i >= 0) {
                    CrossXingYouShanShuiTeamMapData mapDataIfNull = getCrossXingYouShanShuiTeamMapDataIfNull(teamId, i);
                    if(mapDataIfNull != null) {
                        builder.setType(gid);
                        builder.setValue(String.valueOf(mapDataIfNull.getCloseTimes()));
                        syncBuilder.addProps(builder);
                    }
                }
            }
        }


        for (Long uid : userIdList) {
            if(!inMapUserSet.contains(uid)){
                continue;
            }
            UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(uid);
            if(userBaseInfo != null){
                MessageHelper.sendPacket(userBaseInfo.getServerId(), uid, YanQuMessageUtils.buildMessage(Protocol.U_XING_YOU_SHAN_SHUI_TEAM_MEMBER_NOTIFY, syncBuilder));
            }
        }
    }

    public void syncShanShuiPropNotify(int teamId, List<Integer> typeList) {
        CommonTeamActivity activity = CommonTeamMgr.getActivity(config.getActivityInfo().getActivityId(), this.groupId);
        if(activity != null){
            CommonTeam team = activity.getTeam(teamId);
            if(team != null){
                List<Long> userList = new ArrayList<>();
                for (Map.Entry<Long, CommonTeamUserData> entry : team.getMemberDataMap().entrySet()) {
                    if(!inMapUserSet.contains(entry.getKey())){
                        continue;
                    }
                    CrossXingYouShanShuiUserData userData = getUserData(entry.getKey());
                    if(userData.isDrift()){
                        continue;
                    }
                    if(!userList.contains(entry.getKey())){
                        userList.add(entry.getKey());
                    }
                }
                syncShanShuiPropNotify(userList, teamId, typeList);
            }
        }
    }

    public void syncDriftMemberShanShuiPropNotify(int teamId, List<Integer> typeList) {
        CrossXingYouShanShuiTeamData teamData = getTeamData(teamId);
        long timeMillis = System.currentTimeMillis();
        List<Long> userList = new ArrayList<>();
        XingYouShanShuiGridInfo gridInfo = config.getGridInfo(eXingYouGridTypes.Sixteen.getId());
        for (Map.Entry<Long, Long> entry : teamData.getVisitorMap().entrySet()) {
            if(!inMapUserSet.contains(entry.getKey())){
                continue;
            }
            if(entry.getValue() + gridInfo.getParam().get(4) * DateHelper.SECOND_MILLIONS < timeMillis){
                continue;
            }
            userList.add(entry.getKey());
        }
        syncShanShuiPropNotify(userList, teamId, typeList);
    }

    private XingYouShanShuiProto.ShanShuiChallengePlayerInfo.Builder getChallengeBuilder(CommonTeamActivity teamActivity, int memberSize, long nowTimes, CrossXingYouTargetMarkData data, long playerId) {
        XingYouShanShuiProto.ShanShuiChallengePlayerInfo.Builder builder = XingYouShanShuiProto.ShanShuiChallengePlayerInfo.newBuilder();
        builder.setPlayerId(data.getUserId());
        UserBaseInfo baseInfo = CrossUserMgr.getUserBaseInfo(data.getUserId());
        if(baseInfo != null){
            builder.setNickName(baseInfo.getNickName());
        }
        UserBaseInfo info = CrossUserMgr.getUserBaseInfo(data.getTargetUserId());
        if(info != null){
            builder.setEnemy(PlayerBasePb.parsePlayerBaseTempMsg(info));
        }
        CrossXingYouShanShuiUserData shuiUserData = getUserData(data.getTargetUserId());
        CommonTeam team = teamActivity.getTeam(shuiUserData.getTeamId());
        if(team != null){
            builder.setTeamName(team.getTeamName());
        }
        builder.setMarkId(data.getId());
        for (int i = 0; i < data.getTzList().size(); i++) {
            builder.addJointOperationId(data.getTzList().get(i));
        }
        builder.setMarkTime(data.getLogTime());
        builder.setIsReceiveAward(data.getGetReward() == 1);
        builder.setHpPercent(data.getTargetHp());
        builder.setMaxHp(data.getMaxTargetHp());
        builder.setStatus(0);
        if(builder.getHpPercent() > 0){

        }
        return builder;
    }

    private XingYouShanShuiProto.ShanShuiPlayerInfo.Builder getPlayerInfoBuilder(CrossXingYouShanShuiUserData userData) {
        XingYouShanShuiProto.ShanShuiPlayerInfo.Builder playerInfoBuilder = XingYouShanShuiProto.ShanShuiPlayerInfo.newBuilder();
        playerInfoBuilder.setEnergy(userData.getEnergy());
        playerInfoBuilder.setEnergyRecoverTime(userData.getEnergyLastTime());
        playerInfoBuilder.setPlayerId(userData.getUserId());
        playerInfoBuilder.setCoopTimes(userData.getHelpTimes());
        playerInfoBuilder.setLastDeclareTime(userData.getDeclareCd());
        if(userData.getGridParam() != null) {
            XingYouShanShuiProto.ShanShuiEventInfo.Builder curEvent = getCurEventInfoBuilder(userData.getGridParam());
            playerInfoBuilder.setCurEventInfo(curEvent);
        }
        playerInfoBuilder.setLastAbilityUpdateTime(userData.getLastAbilityUpdateTime());
        playerInfoBuilder.setQuickStepTimes(userData.getFlyTimes());
        playerInfoBuilder.setLuckyTimes(userData.getLuckyTimes());
        playerInfoBuilder.setMisfortuneTimes(userData.getMisfortuneTimes());
        playerInfoBuilder.setWishShareLastGetTime(userData.getWishShareLastGetTime());
        return playerInfoBuilder;
    }

    private XingYouShanShuiProto.ShanShuiEventInfo.Builder getCurEventInfoBuilder(ShanShuiGridParam gridParam) {
        XingYouShanShuiProto.ShanShuiEventInfo.Builder curEvent = XingYouShanShuiProto.ShanShuiEventInfo.newBuilder();
        curEvent.setGridId(gridParam.getId());
        curEvent.setPosition(gridParam.getMapIndex());
        curEvent.setEventId(gridParam.getEventId());
        curEvent.setEventParam(gridParam.getEventParam());
        curEvent.setHandle(gridParam.isHandled());
        curEvent.setIsDrift(gridParam.isDrift());
        return curEvent;
    }

    public CrossXingYouShanShuiTeamActionLogData createActionLogData(CrossXingYouShanShuiUserData userData, XingYouShanShuiProto.ShanShuiLogTypeEnum typeEnum, String reward, List<String> paramList) {
        return createActionLogData(userData, typeEnum, reward, StringUtils.listToString(paramList, "&#!"));
    }

    public CrossXingYouShanShuiTeamActionLogData createActionLogData(CrossXingYouShanShuiUserData userData, XingYouShanShuiProto.ShanShuiLogTypeEnum typeEnum, String reward, String params) {
        CrossXingYouShanShuiTeamActionLogData actionLogData = new CrossXingYouShanShuiTeamActionLogData();
        actionLogData.setGroupId(this.groupId);
        actionLogData.setActivityId(userData.getActivityId());
        actionLogData.setUserId(userData.getUserId());
        actionLogData.setLogType(typeEnum.getNumber());
        actionLogData.setTeamId(userData.getTeamId());
        if(!StringUtils.isNullOrEmpty(reward)){
            actionLogData.setReward(reward);
        }
        actionLogData.setParam(params);
        actionLogData.setLogTime(System.currentTimeMillis());
        actionLogData.setInsertOption();
        actionLogData.setDrift(userData.isDrift() ? 1 : 0);
        return actionLogData;
    }

    public XingYouShanShuiProto.ShanShuiEventInfo.Builder getEventInfoBuilder(int pos, int gridId, Property reward, boolean handle) {
        XingYouShanShuiProto.ShanShuiEventInfo.Builder eventBuilder = XingYouShanShuiProto.ShanShuiEventInfo.newBuilder();
        eventBuilder.setPosition(pos);
        eventBuilder.setGridId(gridId);
        eventBuilder.setHandle(handle);
        eventBuilder.setAward(PropertyHelper.parsePropertyToString(reward));
        return eventBuilder;
    }

    /**
     * 修补方法
     */
    public void repair(){

    }

    public Map<Integer, CrossXingYouShanShuiTeamData> getTeamDataMap() {
        return teamDataMap;
    }

    public Map<Long, CrossXingYouShanShuiUserData> getUserDataMap() {
        return userDataMap;
    }

    /**
     * 格子固定奖励
     */
    public Property getGridInfoFixedReward(CrossXingYouShanShuiUserData userData, XingYouShanShuiGridInfo gridInfo, boolean stop){
        if(!stop){
            return new Property();
        }
        if(userData.isDrift()){
            return new Property();
        }
        String reward3 = gridInfo.getReward3();
        if("0".equals(reward3)){
            return new Property();
        }
        if(!StringUtils.isNullOrEmpty(reward3)){
            return RandomWeightConfigHelper.getProperty(reward3);
        }
        return new Property();
    }

    /**
     * 测试指令
     */
    public void testCode(long userId, String code) {
        CrossXingYouShanShuiUserData userData = getUserData(userId);
        List<String> params = StringUtils.stringToStringList(code.substring("/shanshui".length()), "\\s");
        String action = params.get(0);
        if("sliver".equals(action)){
            synchronized (getTeamLocker(userData.getTeamId())){
                CrossXingYouShanShuiTeamData teamData = getTeamData(userData.getTeamId());
                int add = Integer.parseInt(params.get(1));
                teamData.setSilverCoin(teamData.getSilverCoin() + add);
                if(add > 0){
                    userData.setSilverCoinTotal(userData.getSilverCoinTotal() + add);
                    teamData.setSilverCoinTotal(teamData.getSilverCoinTotal() + add);
                }
            }
            syncShanShuiPropNotify(userData.getTeamId(), Arrays.asList(XingYouShanShuiProto.PROP.TEAM_SILVER_VALUE, XingYouShanShuiProto.PROP.TEAM_CUL_SILVER_VALUE));
        }
        if("jump".equals(action)){
            int pos = Integer.parseInt(params.get(1));
            Integer gid = config.getSHANSHUI_MAP().get(pos);
            XingYouShanShuiGridInfo gridInfo = config.getGridInfo(gid);
            DiceHandleResult result = new DiceHandleResult();
            result.setActivity(this);
            result.setConfig(config);
            result.setUserData(userData);
            boolean drift = userData.isDrift();
            handleGrid(gridInfo, pos, gid, pos, false, result);

            ShanShuiGridParam shuiGridParam = null;
            Property property = new Property();
            for (int i = 0; i < result.getGridHandleResultList().size(); i++) {
                GridHandleResult handleResult = result.getGridHandleResultList().get(i);
                XingYouShanShuiProto.ShanShuiEventInfo.Builder eventBuilder = handleResult.getBuilder();
                if(eventBuilder != null){
                    if(eventBuilder.hasAward()){
                        property.addProperty(PropertyHelper.parseStringToProperty(eventBuilder.getAward()));
                    }
                }
                shuiGridParam = handleResult.getGridParam();
            }
            if(shuiGridParam == null){
                return;
            }

            addReward(userData, property, drift, 9);
            if(shuiGridParam.isDrift()){
                userData.setDriftGridParam(shuiGridParam);
            }else {
                userData.setGridParam(shuiGridParam);
            }

            UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(userId);
            if(userBaseInfo != null) {
                enterMapByCmd(userBaseInfo.getServerId(), userId, "");
            }

            syncShanShuiPropNotify(userData.getTeamId(), Arrays.asList(XingYouShanShuiProto.PROP.TEAM_SILVER_VALUE, XingYouShanShuiProto.PROP.TEAM_CUL_SILVER_VALUE));
        }

        if("energy".equals(action)){
            int num = Integer.parseInt(params.get(1));
            userData.setEnergy(userData.getEnergy() + num);
            UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(userId);
            if(userBaseInfo != null) {
                enterByCmd(userBaseInfo.getServerId(), userId);
            }
        }
        if("nextEvent".equals(action)){
            int eventId = Integer.parseInt(params.get(1));
            userData.setTestEventId(eventId);
        }
        if("wish".equals(action)){
            int num = Integer.parseInt(params.get(1));
            if(userData.getGridParam().getId() != eXingYouGridTypes.Thirteen.getId()){
                return;
            }
            //特殊处理，跳过验证
            userData.getGridParam().setBuy(-1000);

            synchronized (getTeamLocker(userData.getTeamId())){
                WishGridHandler wishGridHandler = new WishGridHandler();
                XingYouShanShuiProto.ShanShuiConfirmEventRsp.Builder resp = XingYouShanShuiProto.ShanShuiConfirmEventRsp.newBuilder();

                ConfirmHandleResult handleResult = new ConfirmHandleResult();
                handleResult.setActivity(this);
                handleResult.setBuilder(resp);
                wishGridHandler.confirm(config.getGridInfo(eXingYouGridTypes.Thirteen.getId()), userData, handleResult, num, false);
            }
        }
        if("helpTimes".equals(action)){
            int num = Integer.parseInt(params.get(1));
            userData.setHelpTimes(userData.getHelpTimes() + num);
            UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(userId);
            if(userBaseInfo != null) {
                enterByCmd(userBaseInfo.getServerId(), userId);
            }
        }
    }

    public void dayReset() {
        long todayZeroTimeStamp = DateHelper.getTodayZeroTimeStamp();

        if(shanShuiData.getDayRestTime() == todayZeroTimeStamp){
            return;
        }
        shanShuiData.setDayRestTime(todayZeroTimeStamp);

        for (Map.Entry<Integer, CrossXingYouShanShuiTeamData> dataEntry : teamDataMap.entrySet()) {
            CrossXingYouShanShuiTeamData teamData = dataEntry.getValue();
            teamData.setTodayTeam(new ArrayList<>());
        }

        synchronized (lock){
            initMaZu(shanShuiData);
        }

    }

    public ConcurrentHashSet<Integer> getNeedSyncRedDotTeamMap() {
        return needSyncRedDotTeamMap;
    }

    public ConcurrentHashSet<Long> getNeedSyncRedDotUserMap() {
        return needSyncRedDotUserMap;
    }

    /**
     * 补发协助奖励
     */
    public void sendHelpReward() {
        List<CrossXingYouTargetMarkData> markDataList = new ArrayList<>();
        for (Map.Entry<Integer, List<CrossXingYouTargetMarkData>> entry : teamMarkMap.entrySet()) {
            for (int i = entry.getValue().size() - 1; i >= 0; i--) {
                CrossXingYouTargetMarkData markData = entry.getValue().get(i);
                if(markData.getGetReward() == 1){
                    continue;
                }
                if(markData.getTargetHp() > 0){
                    continue;
                }
                markDataList.add(markData);
            }
        }

        if(markDataList.isEmpty()){
            //CrossXingYouShanShuiMgr.getLogger().info("活动 {}， 没有协助奖励需要补发", config.getActivityInfo().getActivityId());
            return;
        }

        XingYouShanShuiGridInfo gridInfo = config.getGridInfo(eXingYouGridTypes.Seventeen.getId());
        if(gridInfo == null){
            CrossXingYouShanShuiMgr.getLogger().info("活动 {}， 协助奖励补发配置不存在", config.getActivityInfo().getActivityId());
            return;
        }

        List<Long> logIdList = new ArrayList<>();
        for (CrossXingYouTargetMarkData markData : markDataList) {
            logIdList.add(markData.getId());
            markData.setGetReward(1);
            addMarkDataUpdate(markData);
        }

        CrossXingYouShanShuiMgr.getLogger().info("活动 {}， 协助奖励需要补发[{}]", config.getActivityInfo().getActivityId(), StringUtils.listToString(logIdList, ","));

        Map<Long, Property> userRewardMap = new HashMap<>();

        for (CrossXingYouTargetMarkData markData : markDataList) {
            if(!userRewardMap.containsKey(markData.getUserId())){
                userRewardMap.put(markData.getUserId(), new Property());
            }
            Property property = RandomWeightConfigHelper.getProperty(gridInfo.getReward1());
            userRewardMap.get(markData.getUserId()).addProperty(property);
        }

        if(userRewardMap.isEmpty()){
            return;
        }

        for (Map.Entry<Long, Property> entry : userRewardMap.entrySet()) {
            long uid = entry.getKey();
            XingYouShanShuiProto.ShanShuiHelpRewardSendMsg.Builder msg = XingYouShanShuiProto.ShanShuiHelpRewardSendMsg.newBuilder();
            msg.setUserId(uid);
            msg.setReward(PropertyHelper.parsePropertyToString(entry.getValue()));
            MessageHelper.sendPacket(Protocol.S_XING_YOU_SHAN_SHUI_HELP_AUTO_REWARD_FROM_CROSS, msg, uid);
        }

    }
}
